Why can I return `int` after a function but not `char *`?

  • A+
Category:Languages

I'm a newbie to C. I had extended the question from the previous question: Strange behavior when returning "string" with C (Thanks for all who answered or commented that question, by the way.)

Pretty straight forward:

Why can this work:

#include <stdio.h>  int func() {     int i = 5;     return i; }  int main() {     printf("%d",func()); } 

But not this:

#include <stdio.h>  char * func() {     char c[] = "Hey there!";     return c; }  int main() {     printf("%s",func()); } 

From the previous question, logically the int i should not exist too because the function has returned, but why can it still be returned while char c[] cannot?

(It seems to be duplicated from "Pointers and memory scope" but I would like to know more about what is the difference between returning an int and a char *.)

 


Problem is not returning char *, it is returning something that is allocated on stack.

If you allocate memory for your string rather than pointing to function stack, there will be no problem. Something like this:

char * func() {     char c[] = "Hey there!";     return strdup(c); }  int main() {     char* str = func();     printf("%s", str);     free(str); } 

It is important to mention that in both cases, you are copying a value and in both cases copied value is correct, but the meaning of copied value differs.

In first case, your are copying an int value and after your return from function, you are using that int value which will be valid. But in 2nd case, even though you have a valid pointer value, it refers to an invalid address of memory which is stack of called function.

Based on suggestions in comment, I decided to add another better practice in memory allocating for this code:

#define NULL (void*)0  int func(char *buf, int len) {     char c[] = "Hey there!";     int size = strlen(c) + 1;      if (len >= size) {         strcpy(buf, c);     }      return size; }  int main() {     int size = func(NULL, 0);     char *buf = calloc(size, sizeof(*buf));     func(buf, size);     printf("%s", buf);     free(buf);     return 0; } 

Similar approach is used in a lot of windows API functions. This approach is better, because owner of pointer is more obvious (main in here).

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: