C语言 字符数组在函数之间传递指针后损坏



我已经学习C语言几个星期了。我已经通过使用malloc()在堆上分配一些内存解决了我的问题。我对为什么我的代码失败有一个暗示,但我不是 100% 确定。不幸的是,我是自学成才的,所以我不得不求助于互联网上的善良人士。

代码说明调用声明数组的函数getString(),使用内置getchar()填充数组并返回指向该数组的指针。

问题我打印返回的指针值,一切都很好。但是当我把它传递给另一个函数时,它只是把它吐出来并尝试打印出来,字符串的末尾被切断,有时它会吐出一个无意义的字符。

原始数组仅在getString()函数期间使用,因此C使用数组地址中的一些内存来存储其他内容。

我的直觉正确吗?如果没有,有人可以指出我正确的方向吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 100
char * getString(void);
char * doSomethingWith(char *);
int main(void)
{
char *string1 = getString();
printf("String: %sn", string1);
char *string2 = doSomethingWith(string1);
printf("String: %sn", string2); // This print out is unreliable!
return EXIT_SUCCESS;
}
char * getString(void) {
int c;
char arr[MAXLEN];
char *string = arr;
char *cur = arr;
while((c = getchar()) != 'n' && c != EOF) {
if(cur - string < MAXLEN - 2) {
*cur++ = c;
}
}
*cur = ''; // Terminate string
return string;
}
char * doSomethingWith(char *string) {
return string;
}

这是我修改后的getString(),它的行为正确。

char * getString(void) {
int c;
char *string = malloc(sizeof *string * MAXLEN);
char *cur = string;
while((c = getchar()) != 'n' && c != EOF) {
if(cur - string < MAXLEN - 2) {
*cur++ = c;
}
}
*cur = ''; // Terminate string
return string;
}

更新:感谢您的所有答案!非常感谢。

char *string = arr;是错误的,因为你没有arr分配内存;它是堆栈上的一个变量。返回后,堆栈内存将被重新定义,因此返回指向已发布变量的指针。

请改用malloc,例如:

string= malloc(strlen(arr)+1);
strcpy(string,arr);
return string;

>getString返回具有自动存储持续时间的函数局部变量的地址,即arr的地址。在函数返回后,任何通过该地址访问arr的尝试都具有未定义的行为。

C标准不能保证它会保留其价值。不能保证它不会。当你打破这样的语言约束时,编译器甚至没有义务生成一个有效的程序。

6.2.4 对象的存储持续时间 ¶2

对象的生存期是程序执行期间保证为其保留存储的部分。对象存在,具有常量地址,33) 并在其整个生存期内保留其最后存储的值。34) 如果对象在其生存期之外被引用,则行为是未定义的。当指针指向(或刚刚过去)的对象达到其生存期结束时,指针的值将变得不确定。

上面提到的生命周期是从getString的开始大括号到结束大括号,只要它只执行。不多也不少。

最新更新