C语言数组的作用域和生命周期的疑问,附代码

shengxiwgzly 2012-10-31 04:53:41
如果数组定义在函数内,生命周期应该是在函数内部,会被分配在内存栈中,在函数调用完毕时,系统会自动释放栈内资源。
按我理解,函数调用完毕后,外部代码无法获取数组的值。malloc函数分配的空间在堆内,如果程序不主动释放,是一直存在的。
看下面代码:
char* f(){
char a[10];
sprintf(a, "hello_f");
char* ret = (char*) malloc(sizeof(char)*10);
strcpy(ret, a);
return ret;
}

char* f1(){
char a[10];
sprintf(a, "hello_f1");
return a;
}


int main(){
printf("%s\n", f());
printf("%s\n", f1());
}

输出结果是:
hello_f
hello_f1

f()的情况我理解,f1()为什么还可以访问到字符数组里的值,不是应该系统回收了么??数组的生命周期到底是什么啊??
...全文
653 18 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Joseph_1118 2012-11-01
  • 打赏
  • 举报
回复
我的博客有完整的解答!
至善者善之敌 2012-11-01
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]
引用 12 楼 的回复:

引用 11 楼 的回复:

printf也是一个函数,也会占用栈空间

那为什么ubuntu下
printf("%s\n", f());
printf("%s\n", f1());
每次都能输出
hello_f
hello_f1
printf不也应该占用掉栈空间么?

不同编译器不同系统,函数实现不同。要较真的话,就去找源代码,反正linux……
[/Quote]

+++1,可能换个编译器就不一样了
wanglu343280746 2012-11-01
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

引用 1 楼 的回复:

任何变量结束生命周期后依然可以被访问,但不保证这个变量的数据依然可靠


是不是函数内数组在栈中的空间虽然被回收,但是值还在,如果有其它分配,可能把它覆盖了。
[/Quote]
是这样的
baichi4141 2012-11-01
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

引用 11 楼 的回复:

printf也是一个函数,也会占用栈空间

那为什么ubuntu下
printf("%s\n", f());
printf("%s\n", f1());
每次都能输出
hello_f
hello_f1
printf不也应该占用掉栈空间么?
[/Quote]
不同编译器不同系统,函数实现不同。要较真的话,就去找源代码,反正linux上的东西都是开源的。
例如,同样是在函数里定义一个大数组,如果初始化,那么这个数组所占用的所有栈内存都将被覆盖,如果没有初始化,那就只有函数中使用的那一部分数据所在的内存被覆盖。
ForestDB 2012-11-01
  • 打赏
  • 举报
回复
能看到不见得就是你的。这是最基本的态度。

所谓的系统回收了,只是你不能再用它了,并不表示你不能看见它,甚至不能阻止你用它,你还可以用它,但是系统不这么认为,系统需要覆盖这一块地方的时候,就直接覆盖了,因为系统认为没有人用了,最后的结果就是,如果你真的用了,然后你的值是不保证一直正确的。
lol321 2012-11-01
  • 打赏
  • 举报
回复
释放一块内存是指这块内可以让其他操作使用,但并不是指系统会将此块内存的数据抹去
shengxiwgzly 2012-10-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

printf也是一个函数,也会占用栈空间
[/Quote]
那为什么ubuntu下
printf("%s\n", f());
printf("%s\n", f1());
每次都能输出
hello_f
hello_f1
printf不也应该占用掉栈空间么?
baichi4141 2012-10-31
  • 打赏
  • 举报
回复
printf也是一个函数,也会占用栈空间
shengxiwgzly 2012-10-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

你的理解是正确的,malloc申请的空间如果没有手动释放,会在程序结束时由系统释放。你的这种情况是随即的,即你读取的数据时已经成为“垃圾”的数据,也可能是正确的,这种情况是f1的函数栈数据没有被其他函数栈冲刷或者说是占用,所以还保留原来的字符串信息。但是这不代表就是一定是正确的。你可以先执行f();函数,然后在执行f1();函数试一试;

int main(){
char *str1 =……
[/Quote]
恩,是,先调用f1再调用f就得不到数组的值了。
不过我是这样
int main(){
printf("%s\n", f1());
printf("%s\n", f());
}
而不是你的代码
int main(){
char *str1 = f1();
char *str2 = f();
printf("%s\n", str1);
printf("%s\n", str2);
}

这就又有点不懂了,为什么我printf("%s\n", f1());的时候还没执行f()呢,怎么栈里的数据就没了啊??
shengxiwgzly 2012-10-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

你的理解是正确的,malloc申请的空间如果没有手动释放,会在程序结束时由系统释放。你的这种情况是随即的,即你读取的数据时已经成为“垃圾”的数据,也可能是正确的,这种情况是f1的函数栈数据没有被其他函数栈冲刷或者说是占用,所以还保留原来的字符串信息。但是这不代表就是一定是正确的。你可以先执行f();函数,然后在执行f1();函数试一试;

int main(){
char *str1 =……
[/Quote]
恩,是,先调用f1再调用f就得不到数组的值了。
不过我是这样
int main(){
printf("%s\n", f1());
printf("%s\n", f());
}
而不是你的代码
int main(){
char *str1 = f1();
char *str2 = f();
printf("%s\n", str1);
printf("%s\n", str2);
}

这就又有点不懂了,为什么我printf("%s\n", f1());的时候还没执行f()呢,怎么栈里的数据就没了啊??
shengxiwgzly 2012-10-31
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

你的理解是正确的,malloc申请的空间如果没有手动释放,会在程序结束时由系统释放。你的这种情况是随即的,即你读取的数据时已经成为“垃圾”的数据,也可能是正确的,这种情况是f1的函数栈数据没有被其他函数栈冲刷或者说是占用,所以还保留原来的字符串信息。但是这不代表就是一定是正确的。你可以先执行f();函数,然后在执行f1();函数试一试;

int main(){
char *str1 =……
[/Quote]
恩,是,先调用f1再调用f就得不到数组的值了。
不过我是这样
int main(){
printf("%s\n", f1());
printf("%s\n", f());
}
而不是你的代码
int main(){
char *str1 = f1();
char *str2 = f();
printf("%s\n", str1);
printf("%s\n", str2);
}

这就又有点不懂了,为什么我printf("%s\n", f1());的时候还没执行f()呢,怎么栈里的数据就没了啊??
toadzw 2012-10-31
  • 打赏
  • 举报
回复
首先代码是不安全的,
可以外部送空间或者内部分配但要释放
shengxiwgzly 2012-10-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

[/Quote]
有,我刚也试了在windows下确实和你的结果一样。不过我在ubuntu下gcc每次都一样,如下图:


这是因为操作系统还是编译器的问题,为什么会这样啊??
自信男孩 2012-10-31
  • 打赏
  • 举报
回复
你的理解是正确的,malloc申请的空间如果没有手动释放,会在程序结束时由系统释放。你的这种情况是随即的,即你读取的数据时已经成为“垃圾”的数据,也可能是正确的,这种情况是f1的函数栈数据没有被其他函数栈冲刷或者说是占用,所以还保留原来的字符串信息。但是这不代表就是一定是正确的。你可以先执行f();函数,然后在执行f1();函数试一试;

int main(){
char *str1 = f1();
char *str2 = f();
printf("%s\n", str1);
printf("%s\n", str2);
}
再试一下,或许得到就不是开始的内容了。

lin5161678 2012-10-31
  • 打赏
  • 举报
回复
lin5161678 2012-10-31
  • 打赏
  • 举报
回复
shengxiwgzly 2012-10-31
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

任何变量结束生命周期后依然可以被访问,但不保证这个变量的数据依然可靠
[/Quote]

是不是函数内数组在栈中的空间虽然被回收,但是值还在,如果有其它分配,可能把它覆盖了。
baichi4141 2012-10-31
  • 打赏
  • 举报
回复
任何变量结束生命周期后依然可以被访问,但不保证这个变量的数据依然可靠

70,021

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧