用C语言分配开辟内存问题

当我定义一个局部变量int a,在内存中是怎么样开辟的,随机的还是操作系统有他开辟的规则?如果我用new 动态开辟一个空间,书上说是在堆栈中开辟的,堆栈是一个专门的内存区域吗?用int a这样会不会出现内存分配重叠的问题,我用VC编程序就碰到过这样的问题,在一个类中定义了十个变量,刚开始运行没问题,可当我再加一个变量运行就出现一个内存地址出现错误的对话框,随便加一个变量也是,再另外一台机子上也是这样的问题.请问这个问题是怎么回事?
非常感谢三楼和四楼的详解,还有个问题,就是如果我用new或malloc来动态分配的空间,如果我在程序中没有delete或free释放,当我退出程序时那些被分配的内存空间是不是还是占用了?我做过一个例子,当我用
int *pint;
for(int i=0;i<100000;i++)
pint=new int;
没释放内存的语句,运行程序的时候内存是直线上升,当在运行一段时间后我直接关闭了程序,而我看任务管理器的内存也是一下就降下来了,那这说明是不是用new分配的空间当程序关系时内存自动释放的?前后有矛盾了..不明白..

针对你的问题补充我继续回答:
你用new或malloc申请内存后,系统会为你分配在堆区的内存,系统会标记内存已经被占用了,你在程序中不释放,那么在程序运行期间这些内存一直都被系统标记为只读的,其他的程序不能使用,那么这就叫做内存泄露。你的程序运行结束了,还保留着,直到电脑重启了,内存初始化了,才会释放,所以你可以知道内存泄露的危害了,在大型程序中,很可怕的。 至于你说任务管理器的内存也是一下就降下来了,那就涉及到进程的知识了
还有什么不明白的,你可以继续问……
==============================================================
这个问题才有意思
恩,我接着楼上的讲吧 ,我说windows系统的
楼上的 memorymyann说的都对
定义的局部变量,在程序编译的时候,编译器会建立函数栈,然后局部变量存放于栈中,windows系统中,栈大小为2M ,其他楼上都说了
下一个:new和malloc()分配的空间都是在堆区,堆你就可以随意申请了,系统会在系统空闲的链表中找出你要申请空间的大小,标志为已经使用了,然后就会给你用 在申请空间后,注意检测一下申请空间返会值,为NULL就是系统给你分配空间失败了,用完了之后,你需要delete或free()掉你申请的,然后系统就会标记为没有使用了
多看些内存管理的书也许对你的提高有好处
好好学习吧,兄弟……
温馨提示:答案为网友推荐,仅供参考
第1个回答  2016-01-14
1、这个空间是自己分配的,既然已经写了p=(int *)malloc(10000)那就分配10000的大小,还需要显示多少大小。对于一个指向一块内存的指针如果用比如sizeof(p)显示大小(int * p=new int[10]),也只是显示4,代表首地址大小,不能显示正块内存的大小,而且根本没有意义。
2、动态内存分配,可以自由的分配指定大小的内存空间。当程序运行时,程序员并不清楚某一数据需要的具体内存空间大小时,可以使用动态分配。
  malloc函数原型
  void *malloc(int nSize)
  分配一个nSize大小的内存空间,如果分配成功则返回地址空间的首地址,如果分配失败则返货NULL
  nSize一般使用 sizeof(类型A)*N 的计算方式获取大小。意思为:为分配n个类型A所占空间的大小。
  获取的指针地址需要强制转换为指定类型
例如:int *p = (int*)malloc(sizeof(int)*100);
  使用malloc动态分配的内存空间需要使用free函数手动释放。
第2个回答  2008-11-05
你的代码不是C的,其实现在语言比较强大,也许在内存回收上做了完善,我不会C++,我知道JAVA语言,他本身在内存回收上面做了优化,就是在堆中申请的内存,操作系统没回收,但JAVA语言最终编译成可运行码的时候,回收了这块内存(JAVA的垃圾回收机制,蛮强的,不过我不太喜欢)。你可以试试用C写,用malloc 来申请,这个应该不会被回收的,你可以试试,当然可能和其它原因有关。

最后如果你想学习内存管理的话,方向是:操作系统理论中的页式内存管理,地址的印射这2部分是理论(比较简单,实际情况比这复杂一点,先看理论比较好)
等真的明白了(应该不难懂),下面就有难度了,选一个比较流行的CPU的地址映射(各种不同的CPU地址映射是不一样的),我看的是intel 80386后出现的保护模式(其实是286后出现的,不过286没什么名气),以及linux中内存管理的源代码(记得结合书看,直接看代码很难懂)。
==========================================

你的问题算是有点难度和深度的。

关于内存开辟问题,在linux中有个很特殊的内存段,它的大小是8K,我们叫他系统堆栈空间,任何一段程序代码在运行时候它都是一个进程,它都会有这么一个8K的系统堆栈空间。局部变量都是放在这样一个8K空间中,包括int a,int a[100], int *a.他们都放在这里。

那么第一个问题就回答了,int a就是放在系统堆栈空间中。当这个进程死亡的时候,会有其它的进程来回收这个空间(它自己会指定的,一般是其父进程),所以你不需要自己手动去释放局部变量占地内存。

至于int * a;然后你new一个空间这个就有点不同了,首先 * a还是个局部变量,他是存在于系统堆栈中。不过它存的比较特殊是一个逻辑地址,不是一个值(其实逻辑地址也就是一个无符号的16位整数而已)。当你new 的时候,会在堆空间中开一个空间,并把这个空间的地址放到刚那个 a中去。很明显新申请的空间不是在系统堆栈空间中,父进程(一般是)是不会回收这个内存的,这就是为什么你要自己 free(a) 这样来释放空间。

我们常说局部变量不要过大,比如int a[10000]这是不允许的,可以看出来只有8K的大小的内存,而且他还不全部都是给局部变量使用,他有相当一部分内存是给进程控制块和中断返回现场用的(读过linux源代码你就清楚了),另外C语言不检查数组边界,如果你int a[4]数组,而不顾一切的向这个数组上放东西,你就有可能很运气的把中断的返回地址给冲掉,聪明的人会放一个新的返回地址进去,而这个地址返回一个恶意的进程。知道会发生什么了,这就是缓冲区溢出攻击。

windows虽然不太一样,但原理差不多。
第3个回答  推荐于2018-03-01

    使用C语言分配堆内存,需要使用stdlib.h提供的malloc函数。

函数原型:

void *malloc(unsigned int num_bytes);

参数:

        num_bytes:要分配的空间大小,单位为字节。

返回值:

        分配成功则返回指向该内存的指针,分配失败则返回NULL。

注意:使用malloc分配的堆内存,系统不会自动回收,因此,程序使用完之后,应该调用free函数释放这块内存。

本回答被网友采纳
第4个回答  2008-11-03
c语言中有全局变量、本地变量、静态变量和寄存器变量。每种变量都有不同的内存分配方式。

对于一个进程的内存空间来说,可以在逻辑上分为三个部分:代码区、静态数据区和动态数据区。动态数据区就是我们说的堆栈了,他们分为堆和栈,是两种不同的动态数据区。栈是线性结构的,堆是一种链式结构。

全局变量:分配在静态数据区。
局部变量:分配在动态数据区的栈中。
用new动态开辟的空间:分配在动态数据区的堆中的,需要程序员自己管理这里的内存。
相似回答