1. 函数执行完成时,里面的局部静态变量所占的内存会被自动释放
首先看个简单的例子程序:
#include <stdio.h>
int f(){
int j=20;
return j;
}
int main(){
int i;
i = f();
return 0;
}
能够见到上面 main函数 调用了f()函数, 而f()里面定义了1个整形变量j.
问题是, 若是f()被调用完成后, 也就是 i=f(); 这条语句执行完后, f()里面的j所占的内存还存在吗?
答案是否. 首先j是1个局部变量, 并且j是1个静态分配变量, 因此当f() 结束时, f()里面的局部静态分配内存的变量所占的内存都会被自动释放.
注意静态分配内存的变量不必定是静态变量(static 前序)
若是不释放有什么后果? 假如f() 在不一样的地方被调用了1000次, 那么里面的j就占用了4byte * 1000 接近4MB的内存, 可用内存就会愈来愈少.
2. 内存空间传递的方式--内存头部字节的地址(指针)
那么main() 函数有无可能使用f函数定义的内存空间呢?
上面讲到, 局部静态分配内存变量确定不行了, 由于一旦f() 被执行完. 里面的静态分配内存的变量所占内存会被释放嘛...
那么假如f() 里面分配了1块内存(连续的), 若是main函数要得到内存的内容, 则必须得到这块内存的地址, 咱们知道内存里每1个单元都有1个内存地址. 由于这块内存是物理连续的, 咱们之须要得到内存头部地址就ok了
那么f() 怎么把地址穿给main呢?
第一步确定是 在mian里定义1个指针, 用于接受这个地址.
第二步呢?
3. 三个利用函数给指针赋值的例子.
就如一条选择题. 下面3个程序能能给main里的指针p 得到1个合法的变量地址呢?
A)
void f(int *q){
int j=20;
q=&j;
}
int main(){
int *p;
f(p);
return 0;
}
咱们先看看例子A, 在main函数里定义1个 指针变量p, 而后把指针变量p做为参数传递给f, 而后f里面给这个参数赋值..
首先main函数里的变量p 自己就是1个指针变量, 而f的形参也是指针变量, 因此这个传递其实是按值传递
稍稍有点编程基础的都知道按值传递的是形参的值是修改不了的. 因此p 做为参数被f(p)执行完. p的值是不变的.
A是错误的.
B)
void f(int ** q){
int j=20;
*q=&j;
}
int main(){
int *p;
f(&p);
return 0;
}
咱们来看看B, 见到main是以指针p自己的地址(不是指向的地址)(&p)穿给f, f函数里面把变量j的地址传给了p自己
q = &p ==> *q =
(*&p)= p
因此p的值的确被改变了.
那么B选项是正确的吗?
的确p经过f函数得到了1个地址.
但这个地址是j的地址, 而j是1个局部静态分配内存的变量啊, 上面说过,当 f被执行完. j就会被释放.
也就是虽然p得到了j的地址, 可是j自己被释放了, 因此也不是1个合法的变量地址.
B也是错误的.
C)
#include <stdlib.h>
void f(int ** q){
*q = (int *)malloc(sizeof(int));
**q = 20;
}
int main(){
int *p;
f(&p);
return 0;
}
C..
使用了动态分配内存, 在f函数分配了1个长度为1个int整形长度的内存(4字节), 而后把这个内存的头部地址穿给p.
那么在main里面可否使用这块内存?
答案是能够的啊, 由于在f函数里面. *q 也就是p 指向的内存并无被手动释放啊..
因此C是正确的
由C这个例子咱们能够看出两点:
1) 利用动态分配内存就能够实现跨函数使用这块内存了, 前提是这块内存未必释放.
2) 利用malloc 动态分配的内存, 最终必须手动释放内存.
若是忘记了释放有什么后果, 那么通常要等到程序结束时才会释放这块内存了.
其实也不必定, 咱们平时使用操做系统时是否是以为越用内存越少?
实际上不少操做系统都是由c/c++写成了, 若是程序员忘记手动释放内存, 就会致使内存泄露... 可用内存就愈来愈少.
4. 1个稍稍复杂一点的跨内存使用的例子
其实也不是很复杂啦,
下面这个小程序咱们会定义1个create_list()函数.
利用create_list函数划分1个内存, 传给其余函数.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student * Create_list();
void memory_1();
void Show_list();
int memory_main(){
memory_1();
printf("memory main done\n");
return 0;
}
struct Student{
int sid;
int age;
char name[100];
};
void memory_1(){
struct Student * p = Create_list();
p->sid = 11;
p->age = 24;
strcpy(p->name,"JasonPoon");
Show_list(p);
}
struct Student * Create_list(){
struct Student * pst;
pst = (struct Student *)malloc(sizeof(struct Student)*1);
return pst;
}
void Show_list(struct Student * pst){
printf("sid is %d, name is %s, age is %d\n",pst->sid, pst->name, pst->age);
}
输出:
gateman@GMPC Main $ ./main
sid is 11, name is JasonPoon, age is 24
memory main done