George F-bot
George F-bot

Reputation: 11

String returned from function is wrong

This is my code:

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

And this is my output of 3 (same prog) executes in Linux gcc:

1st:

aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaT��aaaaa

2nd:

aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaa�ƃ�aaaaa 

3rd:

aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaa����aaaaa   

Can't figure out what's wrong and even worse, can't imagine how can i get a different output on every run? variable word can't have garbage in a part of the string right?!

Upvotes: 0

Views: 129

Answers (2)

alk
alk

Reputation: 70911

You return a reference to memory which had been allocated in the stack (array).

This memory is freed autmatically when returning from genWord().

That's why the reference returned does not refer to any valid memory anymore.

To fix this issue

  • either allocate the memory needed by genWord() dynamically (inside genWord()),
  • or pass in a buffer to genWord() (from outside of genWord()), to which you copy the data needed.

As a side note: So called C-strings are zero-terminated. That is the character array representing the string takes a NULcharacter (decimal 0) as its last (terminating) element (which's position would be indexed by the value of i, not by wordLen in your code).

The str*family of functions essentially relies on the terminating 0, to determine the 'length' of the string.

So if building up a string character by character, as genWord() does, make sure to add the terminating 0 after the last element when done. Alternativly (although more expensive, but also more convinient) just initialise the whole buffer with 0s before using it.

Upvotes: 3

phoxis
phoxis

Reputation: 61910

You are returning local address, which is not anymore guaranteed to be allocated after the return from call. Therefore it is an undefined behaviour.

When you do word = array the local address of the array is copied into word variable. After return the calling function has the address, which was the local address in the function. But after the function return the address is not anymore valid, and may be allocated for other purpose, or overwritten or anything.

Do word = strdup (array); OR

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

Upvotes: 3

Related Questions