从函数返回的字符串是错误的

时间:2012-12-16 14:16:51

标签: c memory-management

这是我的代码:

char *genWord(int wordLen){
    char array[wordLen + 1];
    char *word;
    int i;

    for(i = 0; i <= wordLen; i++){
        array[i] = 'a';
    }

    array[wordLen] = '\0';

    //Test1 printf
    printf("%s \n", array);

    word = array;

    //Test 2
    printf("%s \n", word);

    return word;
}

main(){
    char *word;
    int wordLen = 10;

    word = (char *)genWord(wordLen);

    //Test 3
    printf("%s", word);       
}

这是我在Linux gcc中执行的3(相同编程)的输出:

第一

aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaT��aaaaa

第二

aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaa�ƃ�aaaaa 

第三

aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaa����aaaaa   

无法弄清楚什么是错的,更糟糕​​的是,无法想象我怎么能在每次跑步中得到不同的输出?变量字不能在字符串的一部分中有垃圾吗?!

2 个答案:

答案 0 :(得分:4)

您返回对已在堆栈中分配的内存的引用(array)。

genWord()返回时,将自动释放此内存。

这就是为什么返回的引用不再引用任何有效的内存。

解决此问题

  • 动态分配genWord()所需的内存( in genWord()),
  • 或者将缓冲区传递给genWord()(来自genWord()外部),并将所需数据复制到该文件中。

作为旁注:所谓的C字符串是零终止的。也就是说,表示字符串的字符数组将NUL字符(十进制0)作为其最后(终止)元素(其位置将被i的值索引,而不是{代码中的{1}}。

wordLen系列函数基本上依赖于终止str*来确定字符串的“长度”。

因此,如果按字符构建字符串,就像0那样,请确保在完成后的最后一个元素之后添加终止genWord()。另外(虽然更昂贵,但也更方便)只需使用0 s初始化整个缓冲区。

答案 1 :(得分:3)

您正在返回本地地址,该地址不再保证在通话结束后分配。因此,这是一种未定义的行为。

执行word = array时,数组的本地地址将复制到word变量中。返回后,调用函数具有地址,该地址是函数中的本地地址。但是在函数返回之后,地址不再有效,并且可能被分配用于其他目的,或被覆盖或任何其他目的。

执行word = strdup (array);

word = malloc (sizeof (char) * (strlen (array) + 1));
strcpy (word, array);
return word;