char *a(void)
{
char s[]="nksndl";
return s;
}
main()
{
char *p=NULL;
p=a();
printf("%s\n",p);
为什么输出是乱码?
25 个解决方案
#1
char s[]这个变量是在局部函数里面定义和赋值的
当程序退出这个函数时,s会被清理掉的
当程序退出这个函数时,s会被清理掉的
#2
因为你的变量s是函数的局部变量,因此函数结束时,s的生命周期也结束了,其指向的地址空间也就无效了。
#3
char s[]="nksndl";
改为:static char s[]="nksndl";
改为:static char s[]="nksndl";
#4
return 语句不可返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数
体结束时被自动销毁
体结束时被自动销毁
#5
char s[]="nksndl";
改为
char *pS ="nksndl";
改为
char *pS ="nksndl";
#6
但是我单步跟踪过,他传回来的地址是正确的,并且地址里面的内容也没有改变,
并且在main()里用printf("%c\n",*p); 可以一个一个的输出字符串中的内容。
#7
但是我单步跟踪过,他传回来的地址是正确的,并且地址里面的内容也没有改变,
并且在main()里用printf("%c\n",*p); 可以一个一个的输出字符串中的内容。
并且在main()里用printf("%c\n",*p); 可以一个一个的输出字符串中的内容。
#8
char s[]="nksndl";
改成
static char s[]="nksndl";
改成
static char s[]="nksndl";
#9
你返回的是指针的地址,把接口的类型改成char*而不是char
#10
指针的地址 ,赋值给char类型,基本就是乱码吧
#11
不要被表象所迷惑,地址是对的,内容已经被释放了,有可能指向的地址的内容还是暂时对,那是还没有被重写。
像这类获取缓存的函数最好这样写
char *a(void)
{
char* s = new char[n]; //n是申请的字节数
... //处理缓冲区内容
return s;
}
这类函数用完一定要带一个Release函数。
void a_release(char*s)
{
delete [] s;
}
大家都知道好多函数用完一定要release,大都是这个道理。
#12
返回的是哪个指针的地址?没想明白
#13
改成
static char s[]="nksndl";
static char s[]="nksndl";
#14
谢谢各位的回答,我不是要一个解决方法(这个解决方法自己也可以想到),而是出现乱码的原因
#15
字符数组的情况与一般的变量是不同的。
比如:
int a(void)
{
int s=1;
return s;
}
main()
{
int b;
p=a();
printf("%d\n",p);
}这样的代码没有问题,因为在return s时,会产生一个临时的变量将s的值复制进去,然后给b。
但是问题在于你的代码中return s;时,s是数组名,其实只是一个地址,复制时也只会复制这个地址,并不会将整个数组的内容都复制下来,所以main中的char *p得到的只是一个地址,而局部变量在函数结束之后就会被收回,所以这个地址已经是无效的了。
你上面的代码有可以是乱码,有可能不是乱码,取决于这块已经被收回的地址的内容有没有被写入新的内容,这个基本上是随机的。
#16
p=a();
程序运行到这里时,p里面的确就是"nksndl",虽然临时变量被释放掉了,但只要内存没有被重新写入,则会一直保留,当你执行如下语句的时候:
printf("%s\n",p);
注意,printf是一个函数,一进入这个函数的时候,会申请一些变量(可以调试进去看),这些申请的变量将写入原来"nksndl"所占的内存,所以是乱码(因为被重写了);
当你执行如下语句的时候:
printf("%c\n",*p);
由于*p是在调用printf函数之前运算的,也就是说,先计算*p,得到一个字符,然后将这个字符传入printf函数,而这个字符可是按值传递的,所以到了printf函数里面,就算"nksndl"被重写,已经不影响到输入的值了,这个输入的值(就是字符n)已经与内存地址p没有关系了,相当于:
p=a();
char c = *p;
printf("%c\n", c);
程序运行到这里时,p里面的确就是"nksndl",虽然临时变量被释放掉了,但只要内存没有被重新写入,则会一直保留,当你执行如下语句的时候:
printf("%s\n",p);
注意,printf是一个函数,一进入这个函数的时候,会申请一些变量(可以调试进去看),这些申请的变量将写入原来"nksndl"所占的内存,所以是乱码(因为被重写了);
当你执行如下语句的时候:
printf("%c\n",*p);
由于*p是在调用printf函数之前运算的,也就是说,先计算*p,得到一个字符,然后将这个字符传入printf函数,而这个字符可是按值传递的,所以到了printf函数里面,就算"nksndl"被重写,已经不影响到输入的值了,这个输入的值(就是字符n)已经与内存地址p没有关系了,相当于:
p=a();
char c = *p;
printf("%c\n", c);
#17
指向已经释放了的内存空间,值已经是不可预料的了,出现了乱码有什么奇怪?
#18
仔细看了你的回答,感觉有点明白了,但是我还试了试用for循环 依次执行printf(“c%”,*p++);也能输出整个字符串,难道在这个过程当中前面一次的printf函数的执行没有修改掉字符串的值?
#19
char* fun()
{
char buff[] = "123456";
return buff;
}
char* p = fun();
int n = strlen(p);
for (i = 0; i < n; ++i)
{
printf("%c\n", *p++);
}
是这样吗?只有第一个不是乱码,后面的都是乱码。你的代码怎样?注意,如果你这样:
printf("%c %c %c\n", *p, *(p + 1), *(p + 2));
打出来的,都是正常的字符,原因我在上一贴已经说过了。
#20
函数结束时销毁栈,因此你不能返回栈上的指针,除非你new出来的
#21
看来问题已经解决了。。。。返回千万别放回指向局部变量的指针
#22
当然是这样,我也不至于那么笨,呵呵
#23
这就是所谓的野指针,该内存地址的内容已经被系统回收,其内容具有不确定性。
#24
把你的完整代码贴上来,无论是理论上,还是我自己实际操作,都是乱码(只有第一个字符是正常的)。
#25
以前的代码弄丢立刻,现在重新写了一个,确实是乱码,可能我以前程序哪里弄错了,现在明白了,谢谢你的回答。
#1
char s[]这个变量是在局部函数里面定义和赋值的
当程序退出这个函数时,s会被清理掉的
当程序退出这个函数时,s会被清理掉的
#2
因为你的变量s是函数的局部变量,因此函数结束时,s的生命周期也结束了,其指向的地址空间也就无效了。
#3
char s[]="nksndl";
改为:static char s[]="nksndl";
改为:static char s[]="nksndl";
#4
return 语句不可返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数
体结束时被自动销毁
体结束时被自动销毁
#5
char s[]="nksndl";
改为
char *pS ="nksndl";
改为
char *pS ="nksndl";
#6
但是我单步跟踪过,他传回来的地址是正确的,并且地址里面的内容也没有改变,
并且在main()里用printf("%c\n",*p); 可以一个一个的输出字符串中的内容。
#7
但是我单步跟踪过,他传回来的地址是正确的,并且地址里面的内容也没有改变,
并且在main()里用printf("%c\n",*p); 可以一个一个的输出字符串中的内容。
并且在main()里用printf("%c\n",*p); 可以一个一个的输出字符串中的内容。
#8
char s[]="nksndl";
改成
static char s[]="nksndl";
改成
static char s[]="nksndl";
#9
你返回的是指针的地址,把接口的类型改成char*而不是char
#10
指针的地址 ,赋值给char类型,基本就是乱码吧
#11
不要被表象所迷惑,地址是对的,内容已经被释放了,有可能指向的地址的内容还是暂时对,那是还没有被重写。
像这类获取缓存的函数最好这样写
char *a(void)
{
char* s = new char[n]; //n是申请的字节数
... //处理缓冲区内容
return s;
}
这类函数用完一定要带一个Release函数。
void a_release(char*s)
{
delete [] s;
}
大家都知道好多函数用完一定要release,大都是这个道理。
#12
返回的是哪个指针的地址?没想明白
#13
改成
static char s[]="nksndl";
static char s[]="nksndl";
#14
谢谢各位的回答,我不是要一个解决方法(这个解决方法自己也可以想到),而是出现乱码的原因
#15
字符数组的情况与一般的变量是不同的。
比如:
int a(void)
{
int s=1;
return s;
}
main()
{
int b;
p=a();
printf("%d\n",p);
}这样的代码没有问题,因为在return s时,会产生一个临时的变量将s的值复制进去,然后给b。
但是问题在于你的代码中return s;时,s是数组名,其实只是一个地址,复制时也只会复制这个地址,并不会将整个数组的内容都复制下来,所以main中的char *p得到的只是一个地址,而局部变量在函数结束之后就会被收回,所以这个地址已经是无效的了。
你上面的代码有可以是乱码,有可能不是乱码,取决于这块已经被收回的地址的内容有没有被写入新的内容,这个基本上是随机的。
#16
p=a();
程序运行到这里时,p里面的确就是"nksndl",虽然临时变量被释放掉了,但只要内存没有被重新写入,则会一直保留,当你执行如下语句的时候:
printf("%s\n",p);
注意,printf是一个函数,一进入这个函数的时候,会申请一些变量(可以调试进去看),这些申请的变量将写入原来"nksndl"所占的内存,所以是乱码(因为被重写了);
当你执行如下语句的时候:
printf("%c\n",*p);
由于*p是在调用printf函数之前运算的,也就是说,先计算*p,得到一个字符,然后将这个字符传入printf函数,而这个字符可是按值传递的,所以到了printf函数里面,就算"nksndl"被重写,已经不影响到输入的值了,这个输入的值(就是字符n)已经与内存地址p没有关系了,相当于:
p=a();
char c = *p;
printf("%c\n", c);
程序运行到这里时,p里面的确就是"nksndl",虽然临时变量被释放掉了,但只要内存没有被重新写入,则会一直保留,当你执行如下语句的时候:
printf("%s\n",p);
注意,printf是一个函数,一进入这个函数的时候,会申请一些变量(可以调试进去看),这些申请的变量将写入原来"nksndl"所占的内存,所以是乱码(因为被重写了);
当你执行如下语句的时候:
printf("%c\n",*p);
由于*p是在调用printf函数之前运算的,也就是说,先计算*p,得到一个字符,然后将这个字符传入printf函数,而这个字符可是按值传递的,所以到了printf函数里面,就算"nksndl"被重写,已经不影响到输入的值了,这个输入的值(就是字符n)已经与内存地址p没有关系了,相当于:
p=a();
char c = *p;
printf("%c\n", c);
#17
指向已经释放了的内存空间,值已经是不可预料的了,出现了乱码有什么奇怪?
#18
仔细看了你的回答,感觉有点明白了,但是我还试了试用for循环 依次执行printf(“c%”,*p++);也能输出整个字符串,难道在这个过程当中前面一次的printf函数的执行没有修改掉字符串的值?
#19
char* fun()
{
char buff[] = "123456";
return buff;
}
char* p = fun();
int n = strlen(p);
for (i = 0; i < n; ++i)
{
printf("%c\n", *p++);
}
是这样吗?只有第一个不是乱码,后面的都是乱码。你的代码怎样?注意,如果你这样:
printf("%c %c %c\n", *p, *(p + 1), *(p + 2));
打出来的,都是正常的字符,原因我在上一贴已经说过了。
#20
函数结束时销毁栈,因此你不能返回栈上的指针,除非你new出来的
#21
看来问题已经解决了。。。。返回千万别放回指向局部变量的指针
#22
当然是这样,我也不至于那么笨,呵呵
#23
这就是所谓的野指针,该内存地址的内容已经被系统回收,其内容具有不确定性。
#24
把你的完整代码贴上来,无论是理论上,还是我自己实际操作,都是乱码(只有第一个字符是正常的)。
#25
以前的代码弄丢立刻,现在重新写了一个,确实是乱码,可能我以前程序哪里弄错了,现在明白了,谢谢你的回答。