标签:
操作系统给程序运行的内存分配了4个区域:
1. 代码区:顾名思义就是存放运行的代码的;
2. 全局数据区:存放全局数据和静态数据以及常量;
3. 栈区: 函数调用时的返回地址,参数压栈,局部变量,返回数据等都存放在栈区;
4. 堆区: 存放程序动态分配的内存(new,malloc等函数分配的)。
栈内存是由系统自己分配和释放的,而堆内存要由程序员自己全全控制的,否则会出现内存泄露.
例子:
#include <stdio.h> #include <stdlib.h> #include <windows.h> int * test1() { // 变量a由系统自动分配在栈上,函数调用结束后就会自动由系统销毁 int a = 10; return &a; } int * test2() { // malloc函数分配的空间是在堆上,函数调用结束后空间还在 int * a = (int *)malloc(sizeof(int)*10); * a = 10; return a; } int main() { int *p, *q; int k = 5; // 重复多次观察变化 while (k--){ p = test1(); //先打印出地址 printf("p = 0x%x ", p); //再打印出变量值 printf("*p = %d\n", *p); Sleep(1000); } // 重复多次观察变化 k = 5; while(k--) { q = test2(); //先打印出地址 printf("q = 0x%x ", q); //再打印出变量值 printf("*q = %d\n", *q); Sleep(1000); } return 0; }
编译后有warning:
运行结果:
分析:
test1()函数中a变量保存在栈上,函数调用结束的时候a的值会释放掉,所以返回后,虽然a的地址还在,但是打印出来时a地址上的值就会变成随机值了。又由于常量10应该是固定的,所以每次打印的地址都是没有变化的。
test2()函数中用malloc函数分配空间,保存在堆上,堆上的内容是需要手动申请和释放的,不会被系统自动清除,所以返回的变量a的地址,里面保存的值还是在那里,所以能打印出10,又由于是每次都重新malloc的,所以地址会有变化,导致每次地址不一样,而且可以看到内存是连续分配的。
test2()中的内存空间没有释放,在每次循环里加上free(q),如下:
while(k--) { q = test2(); //先打印出地址 printf("q = 0x%x ", q); //再打印出变量值 printf("*q = %d\n", *q); free(q); Sleep(1000); }
这样的话,就能释放掉由malloc开辟的内存,但是结果跟上面有点变化,如图:
可以看到q的地址每次都是这样,可能的解释是,内存按顺序分配,这里每次q申请完内存后又由free释放掉了,所以下次申请的时候还是这一块内存。
总结:
函数里可以返回指针变量,但是不要返回由系统自动分配的变量的指针(局部变量),只能返回手动分配的内存的指针(有malloc或new生成的)。
(完)
标签:
原文地址:http://www.cnblogs.com/fwst/p/4689894.html