user-0 提问: 关于 指针和数组的初始化问题

回复:
user: user-1
content: 向http://bbs.csdn.net/topics/392077960的btz201601学习。

user: user-0
content: 引用 17 楼 zhao4zhong1 的回复:[quote=引用 16 楼 songjiajia 的回复:] [quote=引用 14 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 赵老师 13楼的问题帮回答下吧 有点不解！[/quote] 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 [/quote]  多谢您很透彻！ 我尝试之后还是不理解13楼的增加一行打印信息就可以了，这个打印信息起到什么作用呢

user: user-1
content: 引用 16 楼 songjiajia 的回复:[quote=引用 14 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 赵老师 13楼的问题帮回答下吧 有点不解！[/quote] 理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

user: user-0
content: 引用 14 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 赵老师 13楼的问题帮回答下吧 有点不解！

user: user-1
content: 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……

user: user-2
content: 好帖子，学习了，记号

user: user-0
content: 引用 5 楼 scribbler 的回复:没改变程序逻辑，增加一行打印，结果不一样  char* reverseString1(char* s) {     int i= strlen(s)-1;     char restr[i+1];     int j=i;     if(i>1){                  do {             restr[i-j]=s[j];             j--;         } while(j>=0);         //printf("%s,%d\n",restr,(int)strlen(restr));         restr[i+1]='\0';     }    printf("len=%d\n",(int)strlen(restr));    return restr; } int main(int argc, const char * argv[]) {     // insert code here...     char str[100] = "123456";     printf("%s\n",reverseString(str));     return 0; } //6 //654321   为什么增加一行打印信息就可以保留下数据了啊？

user: user-0
content: 引用 3 楼 jianwen0529 的回复:malloc 申请的空间一直有效，知道free掉 栈上的数据，一旦跨出作用域就会被回收，（2）中你的数组作用域在函数内，函数返回之后就咔嚓掉了  strlen 计算字符串长度是不包含 '\0' 结束符的 所以你要完整复制一个字符串，分配的空间至少 strlen(str) + 1;  谢谢！ “栈上的数据，一旦跨出作用域就会被回收” 这个回收的意思是之前的数据被清零了吗？

user: user-1
content: 栈中的变量通常包括函数参数和函数里声明的临时变量。 栈中的基本变量退出其作用域时，没有谁执行一段代码去释放/销毁/析构它所占用的内存，仅仅是没人再去理会的留在当前栈顶上方的若干遗留下来可被后续压栈操作覆盖的无用数据而已。 而栈中的类变量退出其作用域时，会自动执行其析构函数，……

user: user-3
content: 你在函数调用栈里定义的数组只在 函数内部有效 。该次函数调用之后这部分内存会被释放掉。你可以改成static char restr[i+1];储存成静态数组 然后在文件最上面写一个 extern static char restr[i+1];扩展他的作用域，这样就可以用了

user: user-4
content: char* reverseString(char* s) {     int i= strlen(s)-1;    char restr[i+1];     int j=i;     if(i>1){                   do {             restr[i-j]=s[j];             j--;         } while(j>=0);                   restr[i+1]='\0';     }     memcpy(s, restr, strlen(restr)+1);     return s; }  这样就可以了。原因是栈上和堆上的空间生命周期不一样。栈上的数组是随着函数的调用而创建，随着函数的退出而释放。释放之后的空间自然就没有意义了。

user: user-5
content: 函数内部的数组如果没有使用malloc或者new或者外部分配空间的话，那么函数返回后，该内存的数据会释放，最后你获取的是个未知数据。通常你想最终通过函数返回地址得到数据，可以采用：1.外部分配空间，该空间作为函数传出参数。2.内部主动分配，malloc。3使用二重指针

user: user-0
content: 引用 3 楼 jianwen0529 的回复:malloc 申请的空间一直有效，知道free掉 栈上的数据，一旦跨出作用域就会被回收，（2）中你的数组作用域在函数内，函数返回之后就咔嚓掉了  strlen 计算字符串长度是不包含 '\0' 结束符的 所以你要完整复制一个字符串，分配的空间至少 strlen(str) + 1;  谢谢！明白了！

user: user-6
content: 函数结束后，局部变量就销毁了，restr如果是一个局部数组，返回后得到的指针将指向已经销毁的地址  但动态申请的内存只要不释放就会一直存在

user: user-7
content: 没改变程序逻辑，增加一行打印，结果不一样  char* reverseString1(char* s) {     int i= strlen(s)-1;     char restr[i+1];     int j=i;     if(i>1){                  do {             restr[i-j]=s[j];             j--;         } while(j>=0);         //printf("%s,%d\n",restr,(int)strlen(restr));         restr[i+1]='\0';     }    printf("len=%d\n",(int)strlen(restr));    return restr; } int main(int argc, const char * argv[]) {     // insert code here...     char str[100] = "123456";     printf("%s\n",reverseString(str));     return 0; } //6 //654321

user: user-8
content: 使用一个生命周期结束的变量，是未定义行为

user: user-9
content: malloc 申请的空间一直有效，知道free掉 栈上的数据，一旦跨出作用域就会被回收，（2）中你的数组作用域在函数内，函数返回之后就咔嚓掉了  strlen 计算字符串长度是不包含 '\0' 结束符的 所以你要完整复制一个字符串，分配的空间至少 strlen(str) + 1;

user: user-10
content: 栈内存和堆内存的区别，栈内存在作用哉结束后自动释放掉了，堆内存申请后需要代码上用free释放。 第一个是用malloc申请的堆内存，第二个是栈内存数组。 另外永远要记得，要给字符串最后预留一个字节符保存终止符，你申请的内存少了一个字节。

user: user-11
content: 编译器的c++标准不支持栈上动态数组