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

时间:2013-08-24 09:07:58

标签: c string

计划#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语句输出不同。具体描述是什么?

6 个答案:

答案 0 :(得分:10)

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

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

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

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

答案 1 :(得分:3)

char str[] = "GfG";

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

请记住,数组不是通过C中的值传递的,它们是通过地址传递的。由于strgetstring()中定义,因此在控件返回main()后,访问该特定地址无效。如果您确实访问了该地址,则结果将无法预测。请记住,C编译器不会在程序中检查不正确的内存访问请求。

答案 4 :(得分: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

答案 5 :(得分:0)

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

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