2013-08-24 61 views
1

节目#1:为什么这些程序(仅在一个printf语句中有所不同)具有不同的输出?

#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语句输出不同。什么是确切的描述?

+3

请不要大喊。 –

+0

'char * str =“GfG”;'?这对你的问题会是一个有趣的补充。特别是如果你让他们'const char *'。 – trojanfoe

回答

10

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

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

您可以使用字符串文字修改你的程序,因为串文字具有静态存储时间和他们的一生是程序的整个持续时间:

char *getString(void) 
{ 
    char *str = "GfG"; 
    return str; 
} 
+3

对于'return'和'str'都要确保'const char *'。可能某些编译器可能不会强制执行“不允许写入常量字符串”规则。 – trojanfoe

3
char str[] = "GfG"; 

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

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

1

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

+1

这并不能解释任何事情。 – trojanfoe

+1

没有必要像其他人一样重复同样的事情。我的回答告诉我如何解决这个问题。 –

1

只要记住数组中的值不会在C中传递,它们会通过地址传递。由于strgetstring()中定义,在控制返回到main()后,访问该特定地址无效。如果您碰巧访问该地址,结果将不可预知。请记住,C编译器不检查程序中不正确的内存访问请求。

0

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

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

+2

我只是试过了,看起来在第二个版本中,字符串被静静地优化掉了:它不在函数内部使用,并且返回它是UB。所以它只是下降。 – glglgl

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; 
} 

经过下面的链接,你会得到一些更多的例子。 Does local variable be deleted from memory when this function is called in main

相关问题