0

Why does the value of t in stringParser prints "Hello" but not in main function?

#include <stdio.h>

char* stringParser(char st[]) {
    char temp[100];
    int i = 0;
    while (st[i] != '\0') {
        temp[i] = st[i];
        i++;
    }
    temp[i] = '\0';
    char* t = temp;
    printf("%s", t);  
    return t;                // Outputs: "Hello"
}

int main() {
    char y[] = "Hello"; 
    printf("\n%s", stringParser(y));   //Outputs: "╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠⌠²Ö"
    return 0;
}
Hardik Poudel
  • 125
  • 1
  • 8
  • @neostar After exiting the function the returned pointer is invalid because the pointed array that is a local variable of the function with the automatic storage duration is not alive. – Vlad from Moscow Sep 24 '20 at 18:33
  • @Carcigenicate t is a pointer pointing to string temp so the function stringParser() should return that pointer. Shouldn't the pointer from stringParser hold the value of string temp? – Hardik Poudel Sep 24 '20 at 18:35
  • 1
    Look [here](https://godbolt.org/z/fE9Pez) then [here](https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings). – n. m. could be an AI Sep 24 '20 at 18:44
  • @neostar all local variables inside a function are destroyed once the function calls ends, here the variable temp is destroyed so your function returns a pointer which point to temp address but the value of temp has been destroyed – PopJoestar Sep 24 '20 at 18:45
  • 1
    Maybe duplicate of *[Returning string from C function](https://stackoverflow.com/q/25798977/4415884)*? – hiddenAlpha Sep 24 '20 at 19:03
  • @neostar `t` holds only a pointer to the array `temp`, the array `temp` is not copied. If the array `temp` does not exist anymore and you try to dereference the pointer `t` ( or a copy of the pointer, by returning the pointer) you cause UB. – 12431234123412341234123 Sep 24 '20 at 19:04

1 Answers1

1

The array temp exist only in the scope of function stringParser(). The pointer t points to the array temp or in other words t holds the address of where temp is stored. When you return from the function stringParser(), the array temp does no longer exist and accessing it causes undefined behavior (UB). You return the pointer t that points to temp and give it to printf(). printf() dereferences the pointer, means it wants to access the array to which t points to, but the array temp does no long exist and therefore you have UB.

There are multiple ways to avoid UB:

  • Make the array temp static. But that does not work well with multi threading programs and should be avoided in libraries.
  • Use dynamic memory allocation, reserve the storage for the temp-array with malloc() or calloc(), but then you have to free() the memory again after you no longer need it.
  • Declare the array inside main() and pass a pointer to it to stringParser(), but keep the size in check and make sure you never get a buffer overflow.

Off-Topic: size_t is a better type for array indexing, since it is guaranteed to be large enough to hold every possible index and size_t is unsigned. Your program is prone to buffer overflows by future changes. Since you do not document that the string given to stringParser() has to be shorter than 100 chars. You need to document that better, check if the string is not too long or create the array dynamically to be big enough for the given string.