浅谈C#互操作的内存溢出问题

c#调用C++DLL代码,发现了一个隐藏很深的问题。 危害很大,而且不易察觉。

大概是申明c++的函数时候,有一个long类型的指针。在C#中我的申明成了这样:

public extern void Method(ref uint para);

最初怎么也没有发现这里面有什么问题,知道这个隐藏的问题暴露出来,把前面申明的一个变量改变了, 我才恍然大悟。


代码如下:

uint test = 0;
int *p = new IntPtr();
Method(ref test);

在调用Method这里下断点,p的值是分配的一个内存地址。F10跳过Method,p指针就指向了0x00000000!!;

初步分析,是在栈上只给test分配了4个字节存放值,结果通过互操作返回了8个字节的值,就把紧挨着的存放p指针地址的4个字节占用了,恰好这四个字节又是高位,返回数据的高位都是0。 以前了解过c++的栈内存溢出,没想到在c#里被我遇到了,问题看似不大,如何被恰好相邻的四个字节是返回地址,说不定危害不小啊!! 看来c#的互操作还是得小心为好。

(0)

相关推荐

  • C#之CLR内存字符串常量池(string)

    C#中的string是比特殊的类,说引用类型,但不存在堆里面,而且String str=new String("HelloWorld")这样的重装也说没有的. 我们先来看一个方法: class Program { static void Main(string[] args) { String s = "HelloWorld"; Console.WriteLine(s); } } 然后我们用ildasm.exe工具把它生成IL语言来看一看它里面是怎么玩的: .met

  • C#之CLR内存深入分析

    本文不再对值类型进行讨论,主要讨论一下引用类型.如要看内存值类型的朋友可以看一下前一篇C#之CLR内存原理初探. C#引用类型具体分析如下: 先来装备两个类: internal class Employee { public static Employee LookUp(string name) { return null; } public virtual string GetProgressReport() { return string.Empty; } } internal class

  • 深入C# 内存管理以及优化的方法详解

    在C# winform应用程序中,用以下代码可以进行一些内存使用的优化 复制代码 代码如下: using System;using System.Diagnostics;using System.Runtime.InteropServices;/// <summary>/// 包含各种内存管理.优化的方法/// </summary>    public class Memory    {        private static readonly Version myVersio

  • C#之CLR内存原理初探

    本文初步讲述了C#的CLR内存原理.这里所关注的内存里面说没有寄存器的,所以我们关注的只有托管堆(heap),栈(stack), 字符串常量池(其中string是一个很特殊的对象) 首先我们看两个方法: void M1() { string name = "Tom"; M2(name); } void M2(string name2) { int length = 10; double rate = 10.0; name2 = "Joe"; return; } 这里

  • C#反射内存的处理分析

    本文实例分析了C#反射内存的处理.分享给大家供大家参考.具体分析如下: 这段时间由于公司的项目的要求,我利用c#的反射的机制做了一个客户端框架.客户端里的所有的模块都是以一定形式进行提供,例如:FORM,UserControl. 在做的过程中很简单与愉快.具体的过程如下: 1. 收集客户的需求 2. 整理需求,形成必要的文档 3. 通过讨论大体的得到程序的界面风格 4. 由UI设计师设计出来具体的界面形式 5. 通过需求封装必要的服务(我们可以使用c#的WCF服务或者JAVA的服务) 6. 制作

  • asp.net中C#实现手动回收内存的方法

    C#有自动回收内存的机制,但是有时自动回收有一定滞后,需要在变量使用后迅速回收,节约内存,这里介绍一个最简单的方法. 1.先对对象赋值 null; 2.使用System.GC.Collect() 复制代码 代码如下: class Program {          static void Main(string[] args)          {              long lenth = 1024 * 1024 * 128;                GetCost("程序启动

  • C#的内存回收代码

    本文实例讲述了C#的内存回收方法.分享给大家供大家参考.具体实现方法如下: 如下示例代码是调用win32底层操作,可实现内存的回收. 复制代码 代码如下: [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")] public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSi

  • 分享C#操作内存读写方法的主要实现代码

    复制代码 代码如下: using System.Runtime.InteropServices; using System.Text; publicclass Function { //C#操作内存读写方法publicstaticbyte PtrToByte( int Ptr ) { byte b = Marshal.ReadByte( ( IntPtr ) Ptr ); return b; } publicstaticchar PtrToChar( int Ptr ) { byte b = M

  • 使用C#调用系统API实现内存注入的代码

    复制代码 代码如下: //首先导入命名空间 using System.Runtime.InteropServices; /// <summary> /// 在指定进程的虚拟地址空间中保留或开辟一段区域..除非MEM_RESET被使用,否则将该内存区域初始化为0. /// </summary> /// <param name="process">需要在其中分配空间的进程的句柄.这个句柄必须拥有PROCESS_VM_OPERATION访问权限</p

  • 浅谈C#互操作的内存溢出问题

    c#调用C++DLL代码,发现了一个隐藏很深的问题. 危害很大,而且不易察觉. 大概是申明c++的函数时候,有一个long类型的指针.在C#中我的申明成了这样: public extern void Method(ref uint para); 最初怎么也没有发现这里面有什么问题,知道这个隐藏的问题暴露出来,把前面申明的一个变量改变了, 我才恍然大悟. 复制代码 代码如下: uint test = 0;int *p = new IntPtr();Method(ref test); 在调用Meth

  • 浅谈redis采用不同内存分配器tcmalloc和jemalloc

    我们知道Redis并没有自己实现内存池,没有在标准的系统内存分配器上再加上自己的东西.所以系统内存分配器的性能及碎片率会对Redis造成一些性能上的影响. 在Redis的 zmalloc.c 源码中,我们可以看到如下代码: /* Double expansion needed for stringification of macro values. */ #define __xstr(s) __str(s) #define __str(s) #s #if defined(USE_TCMALLOC

  • 浅谈C++对象的内存分布和虚函数表

    c++中一个类中无非有四种成员:静态数据成员和非静态数据成员,静态函数和非静态函数. 1.非静态数据成员被放在每一个对象体内作为对象专有的数据成员. 2.静态数据成员被提取出来放在程序的静态数据区内,为该类所有对象共享,因此只存在一份. 3.静态和非静态成员函数最终都被提取出来放在程序的代码段中并为该类所有对象共享,因此每一个成员函数也只能存在一份代码实体.在c++中类的成员函数都是保存在静态存储区中的 ,那静态函数也是保存在静态存储区中的,他们都是在类中保存同一个惫份. 因此,构成对象本身的只

  • 浅谈Java堆外内存之突破JVM枷锁

    对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收:而使用的内存是由JVM控制的. 那么,什么时机会进行垃圾回收,如何避免过度频繁的垃圾回收?如果JVM给的内存不够用,怎么办? 此时,堆外内存登场!利用堆外内存,不仅可以随意操控内存,还能提高网络交互的速度. 背景1:JVM内存的分配 对于JVM的内存规则,应该是老生常谈的东西了,这里我就简单的说下: 新生代:一般来说新创建的对象都分配在这里. 年老代:经过几次垃圾回收,新生代的对象就会放在年老代里

  • 浅谈Tensorflow2对GPU内存的分配策略

    目录 一.问题源起 二.开发环境 三.Tensorflow针对GPU内存的分配策略 四.问题分析验证 五.GPU分配策略分析 六.扩展 一.问题源起 从以下的异常堆栈可以看到是BLAS程序集初始化失败,可以看到是执行MatMul的时候发生的异常,基本可以断定可能数据集太大导致memory不够用了. 2021-08-10 16:38:04.917501: E tensorflow/stream_executor/cuda/cuda_blas.cc:226] failed to create cub

  • 浅谈Redis中的内存淘汰策略和过期键删除策略

    目录 8种淘汰策略 过期键的删除策略 总结 redis是我们现在最常用的一个工具,帮助我们建设系统的高可用,高性能. 而且我们都知道redis是一个完全基于内存的工具,这也是redis速度快的一个原因,当我们往redis中不断缓存数据的时候,其内存总有满的时候(而且内存是很贵的东西,尽量省着点用),所以尽可能把有用的数据,或者使用频繁的数据缓存在redis中,物尽其用. 那么如果正在使用的redis内存用完了,我们应该怎么取舍redis中已存在的数据和即将要存入的数据呢,我们要怎么处理呢? re

  • 浅谈SQL Server 对于内存的管理[图文]

    理解SQL Server对于内存的管理是对于SQL Server问题处理和性能调优的基本,本篇文章讲述SQL Server对于内存管理的内存原理. 二级存储(secondary storage) 对于计算机来说,存储体系是分层级的.离CPU越近的地方速度愉快,但容量越小(如图1所示).比如:传统的计算机存储体系结构离CPU由近到远依次是:CPU内的寄存器,一级缓存,二级缓存,内存,硬盘.但同时离CPU越远的存储系统都会比之前的存储系统大一个数量级.比如硬盘通常要比同时代的内存大一个数量级. 图1

  • 浅谈Android应用的内存优化及Handler的内存泄漏问题

    一.Android内存基础 物理内存与进程内存 物理内存即移动设备上的RAM,当启动一个Android程序时,会启动一个Dalvik VM进程,系统会给它分配固定的内存空间(16M,32M不定),这块内存空间会映射到RAM上某个区域.然后这个Android程序就会运行在这块空间上.Java里会将这块空间分成Stack栈内存和Heap堆内存.stack里存放对象的引用,heap里存放实际对象数据. 在程序运行中会创建对象,如果未合理管理内存,比如不及时回收无效空间就会造成内存泄露,严重的话可能导致

  • 浅谈PostgreSQL消耗的内存计算方法

    wal_buffers默认值为-1,此时wal_buffers使用的是shared_buffers,wal_buffers大小为shared_buffers的1/32 autovacuum_work_mem默认值为-1,此时使用maintenance_work_mem的值 1 不使用wal_buffers.autovacuum_work_mem 计算公式为: max_connections*work_mem + max_connections*temp_buffers +shared_buffe

  • 浅谈redis key值内存消耗以及性能影响

    一.redis key数量为1千万时. 存储value为"0",比较小.如果value较大,则存储内存会增多 redis key数量为一千万时,使用了865M的内存. # Keyspace db0:keys=11100111,expires=0,avg_ttl=0 内存使用情况 # Memory used_memory:907730088 used_memory_human:865.68M used_memory_rss:979476480 used_memory_rss_human:

随机推荐