1

程序#1:

#include<stdio.h>
#include<stdlib.h>
char *getString()
{
   char str[] = "GfG";
   printf("%s \n", str); 
   return str;
}    
int main()
{
    printf("%s", getString()); 
    return 0;
}

输出:

GfG
GfG

程序#2:

#include<stdio.h>
#include<stdlib.h>
char *getString()
{
    char str[] = "GfG";
    return str;
}    
int main()
{
    printf("%s", getString()); 
    return 0;
}

输出:

(垃圾值)

请解释为什么因为只有一个printf语句输出不同。什么是准确描述?

4

6 回答 6

10

因为这两个程序都显示未定义的行为。

getString函数返回时,str数组对象被销毁并在其生命周期后尝试访问它是未定义的行为。

您可以使用字符串文字修复程序,因为字符串文字具有静态存储持续时间,并且它们的生命周期是程序的整个持续时间:

char *getString(void)
{
    char *str = "GfG";
    return str;
} 
于 2013-08-24T09:09:20.900 回答
3
char str[] = "GfG";

声明一个自动变量。只有在它声明的范围内访问 this 才有效(函数getString)。尝试在其他任何地方使用它会导致未定义的行为。你很不幸第一个版本似乎可以工作。

返回时getString,用于存储的堆栈区域str可能会被重用。如果发生这种情况,printf最终将进一步读取内存,直到找到一个'\0'字节或崩溃。

于 2013-08-24T09:09:46.883 回答
1

您必须使用 分配内存malloc或尝试使用static.

于 2013-08-24T09:13:07.963 回答
1

请记住,数组在 C 中不是按值传递的,而是按地址传递的。由于str在 中定义getstring(),控制返回后main(),访问该特定地址是无效的。如果碰巧访问了该地址,结果将是不可预知的。请记住,C 编译器不会检查程序中不正确的内存访问请求。

于 2013-08-24T09:22:41.613 回答
1

局部变量char str[] = "GfG";范围仅限于函数。因此,当您尝试在函数范围内打印它时,它可以工作。但是当您尝试从该功能之外访问它时undefined behavior.

#include<stdio.h>
#include<stdlib.h>
char *getString()
{
    char str[] = "GfG"; // Local variable, so once you try to return that it is undefined
    return str;
}    
int main()
{
    printf("%s", getString()); 
    return 0;
}

通过以下链接,您将获得更多示例。 在main中调用此函数时是否从内存中删除局部变量

于 2013-08-24T09:24:32.240 回答
0

在这两种情况下,char str[] = "GfG";都放在第一个函数内部的堆栈中。它返回一个指向它的指针。调用者尝试使用它并将其提供给printf(),但与此同时,“旧”堆栈内容已被覆盖。

它们之间可能存在差异,这使得第一个保留旧内容的时间更长一些,但不能保证这一点,因此它是未定义的行为。

于 2013-08-24T09:22:41.810 回答