返回值是指针时子函数的内存释放问题,子函数里增加了printf造成main函数输出结果不同的原因?

reverseString中printf那句不注释,main函数里能够打印出“olleh”,而注释那句后main函数打印出的就是乱码。
reverseString中printf那句不注释为什么主函数里能够打印出“olleh”?
reverseString中注释与不注释printf那句会对s2的内存释产生影响?
还是代码写的有问题?我是在codeblocks上运行的,比较困惑,谢谢!

#include <stdio.h>
#include <stdlib.h>

char* reverseString(char* s) {
    char *p1 = s;
    char s2[100];
    int i = 0;
    char *p2 = s2;
    while(*p1!='\0'){
        ++p1;
        ++i;
    }
    --p1;
    while(i>0){
        (*p2++) = (*p1--);
        --i;
    }
    *p2 = '\0';
    //printf("%s\n",s2);//如果注释这句,主函数会打印乱码;如果不注释则能够打印出"olleh"
    return s2;
}

int main(){
    printf("%s",reverseString("hello"));
    return 0;
}

1个回答

你的程序根本错误在于,你反悔了s2,而s2是堆栈上定义的局部变量,函数返回,堆栈销毁,所以结果不可预料。就算“正确”也不过是侥幸巧合。
你需要动态分配:
char *s2 = new char[100];

sinat_29621543
自自然卷 回复caozhy: 同学帮我在linux上跑了一下,和codeblocks结果一样。取消reverseString中printf的注释后main函数能输出“olleh”,感觉像是编译器之类的优化吧,猜测printf会将要打印的数据所占的内存保留一段时间使它不能被占用。谢谢讨论,之前对内存释放的理解也有问题
3 年多之前 回复
sinat_29621543
自自然卷 回复caozhy: 也许换个IDE结果就不对,但我没试别的编译器不敢下结论,因为昨天在codeblocks上试了很多次了。程序看上去是肯定不对的,但是结果又是对的,我也很无语啊。
3 年多之前 回复
caozhy
每个人都有一个梦才不会孤单的说话就有天堂 回复star-yu: 巧合的意思是这样写能运行是巧合,不一定是说写好的程序运行的时候时好时坏。
3 年多之前 回复
sinat_29621543
自自然卷 回复caozhy: 可是每次结果都是对的啊,现在身边没电脑不好换个字符串试试,中午回去试一下
3 年多之前 回复
caozhy
每个人都有一个梦才不会孤单的说话就有天堂 回复star-yu: 不是,只是巧合了。
3 年多之前 回复
sinat_29621543
自自然卷 回复caozhy: printf("%s\n",s2);会让s2的内存在整个程序结束前都不会被覆盖?如果C是这样那有点不合理了吧,而且是不是这样啊?以前学C用的谭浩强的书,不知道是不是没看仔细,没见到说C有这种特性
3 年多之前 回复
caozhy
每个人都有一个梦才不会孤单的说话就有天堂 回复star-yu: 能不能获得取决于堆栈上s2所在的位置有没有被新的数据覆盖。
3 年多之前 回复
sinat_29621543
自自然卷 回复caozhy: 导致了main函数还能获得s2?
3 年多之前 回复
caozhy
每个人都有一个梦才不会孤单的说话就有天堂 回复star-yu: printf是一个函数,调用函数会操作堆栈
3 年多之前 回复
sinat_29621543
自自然卷 回复caozhy: 嗯,能不能讲下reverseString里取消printf("%s\n",s2);的注释后,在main函数里为什么能够打印出“olleh”?注释与不注释printf("%s\n",s2);对函数返回时候s2的内存产生了什么影响,available not available之类的影响?我不太相信C里printf有这么大的影响,印象里printf就只是个输出语句。
3 年多之前 回复
caozhy
每个人都有一个梦才不会孤单的说话就有天堂 回复star-yu: 因为s2在堆栈上,请注意“释放”和“覆盖”是两回事,你函数返回,堆栈上的变量就已经释放了,释放的意思是这些空间不被承认还在使用。但是上面存的数据直到有新的数据写进来还在那里。
3 年多之前 回复
sinat_29621543
自自然卷 回复caozhy: 你说的没有破坏是说S2的内存没被释放?我比较纠结为什么一个printf会导致s2的内存在函数返回时没被销毁,也不能确定是不是因为printf语句导致了子函数里s2的内存没被销毁。谢谢
3 年多之前 回复
caozhy
每个人都有一个梦才不会孤单的说话就有天堂 回复star-yu: 你调用一个函数,必然对堆栈产生影响。所以恰好堆栈上的数据被破坏了,就出错了,没有破坏就不出错。
3 年多之前 回复
sinat_29621543
自自然卷 谢谢回答!取消子函数中对printf的注释后main函数打印的结果每次都是对的,所以感觉是不是printf对s2内存的释放产生了影响。又感觉C的printf应该没这种奇怪特性
3 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问