为什么从函数返回后 strcpy() 复制的字符串在 C 中为 null

Why string copied by strcpy() after returning from function is null in C

提问人:Abraham Zsombor Nagy 提问时间:6/4/2023 最后编辑:Vlad from MoscowAbraham Zsombor Nagy 更新时间:6/4/2023 访问量:84

问:

我有以下测试:

char* test1()
{
    char* string = "test 1\n";
    printf("In function: %s", string);
    return string;
}

char* test2()
{
    char* string[10];
    strcpy(string, "test 2\n");
    printf("In function: %s", string);
    return string;
}

int main()
{

    printf("After returned: %s", test1());
    printf("After returned: %s", test2());
}

输出:

In function: test 1
After returned: test 1
In function: test 2
After returned: (null)

似乎 in 打印正确,但返回后它变成了 .test2()stringnull

如何正确返回通过 构造的字符串,这种行为的原因是什么?strcpy()

先谢谢你

c 函数 return-value string-literals storage-duration

评论

2赞 Shawn 6/4/2023
返回的指针在函数返回后无效。不能那样做。
3赞 armagedescu 6/4/2023
char* string[10]不是 10 个字符的数组,而是一个 10 指针数组。反正它是一个固定内存的本地块,返回后被丢弃
3赞 Shawn 6/4/2023
如果你打开警告,gcc 至少应该告诉你你在这里做错了几件事。
0赞 Some programmer dude 6/4/2023
局部变量(包括数组)具有定义它们的块的生命周期。在 yout 函数中,当函数返回时,其生存期将结束。您返回的指针(如上所述是错误的)将无效。test2string
1赞 interjay 6/4/2023
你可以重构代码,但不是那样的。通常的方法是将缓冲区指针和长度传递给函数。

答:

2赞 Vlad from Moscow 6/4/2023 #1

该函数返回指向字符串文本的指针test1

char* test1()
{
    char* string = "test 1\n";
    printf("In function: %s", string);
    return string;
}

字符串文本具有静态存储持续时间。也就是说,函数中使用的字符串文字在退出函数后保持活动状态。test1

函数test2

char* test2()
{
    char* string[10];
    strcpy(string, "test 2\n");
    printf("In function: %s", string);
    return string;
}

没有意义并调用未定义的行为。

对于初学者来说,该函数期望其第一个参数具有类型,而用作第一个参数的表达式在将数组指示符隐式转换为指向其第一个元素的指针后具有类型。函数调用中使用的转换说明符也需要该类型的参数,但提供了该类型的参数。strcpy()char *stringchar **%sprintf()char *char **

同样,函数返回类型是,而函数返回如上所述的类型的表达式。char *char **

在退出函数后,使用返回的指向本地数组的指针并自动存储持续时间会调用未定义的行为,因为数组在退出函数后不是活动的。所以返回的指针是无效的。string

评论

0赞 Abraham Zsombor Nagy 6/4/2023
对不起,是错别字,本来是故意的char* string[10]char string[10]
0赞 Vlad from Moscow 6/4/2023
@AbrahamZsomborNagy 这无关紧要,因为在任何情况下,该函数都会返回指向本地数组的指针,该数组在退出函数后将不处于活动状态。
0赞 Aevo 6/4/2023 #2

这是因为第一段代码使用指针返回一个值,该值在函数执行完毕后保持不变,并且在函数 1 执行完毕后仍然可以访问,但是,第二段代码尝试返回一个值,但当它完成执行时,它无法返回该值,因为字符串不再存在于内存中(对于函数 2),因为它是一个字符数组而不是指针, 因此,为什么你得到 null。同样在函数 2 中,字符数组定义为 。对 there 没有要求,否则它将被视为指向类型数组而不是字符数组的指针。char arr[] = "";*char