内存有静态的,就是程序启动的时候就已经分配好的,程序结束回收;比如全局变量,就是放在静态内存区的。
动态的,就是程序执行过程中才动态分配的。
栈内存和堆内存都是动态的内存。
栈内存,程序自己管理的,我的理解是方法栈,一个方法在运行时候是在栈内存运行的,方法中的局部变量在方法结束的时候就会被回收,所以方法返回值时返回局部变量是不对的,如下:
#include<stdio.h>
int* f(int len);
int main(){
int* b = f(10);
printf("%d\n",*b);
return 0;
}
int* f(int len){
int a = len;
int* p = &a;
return p;
}
这里如果返回的是一个值,而不是一个指针那么是可以的,因为返回值时会自动用一个临时的变量来保存要返回的值,如下是正确的:
#include<stdio.h>
int f(int);
int main(){
int b = f(10);
printf("%d\n",b);
return 0;
}
int f(int a){
int b = a;
return b;
}
虽然程序可以编译运行,但是有可能会出现严重错误,因为变量 p 在f方法结束的时候就已经会被回收,所以放回去的时候这块内存有可能已经不是原来的结果,这样就可能导致返回去结果不对导致程序错误。
解决的方法是使用堆内存,堆内存是程序员自己可是开辟的内存,使用完自己释放即可。上面程序如下修改:
#include<stdio.h>
#include<malloc.h>
int* f(int len);
int main(){
int* b = f(10);
printf("%d\n",*b);
free(b);
b = NULL;
return 0;
}
int* f(int len){
// int a = len;
int* p = (int*)malloc(sizeof(int));
*p = len;
return p;
}
还有如下例子,返回一个数组,其余与上例一样:
#include<stdio.h>
#include<malloc.h>
int* f(int size);
int main(){
int* p = f(4);
int i = 0;
for(i=0;i<4;i++){
printf("%d\n",p[i]);
}
//释放内存,否则会内存泄露
free(p);
return 0;
}
int* f(int size){
/*malloc 开辟的内存是没有类型的void类型,所以要强制转换为int类型*/
int* a = (int *)malloc(size*sizeof(int));
int i = 0;
for(i=0;i<size;i++){
a[i] = i;
}
return a;
}
小结:方法不能直接返回局部变量,需要自己在堆内存中开辟内存保存值之后返回,然后自己释放内存,malloc 和 free 成对出现。同时,和java对比一下,java是没有这些限制的,我的理解是:java所有方法的执行都是需要在类 new 出来的对象中的,所以,java是完全面向对象的,可以说java的对象都是在堆内存中的,所以也就不用自己去管返回的是不是方法里面的局部变量了。