2

I wrote the following:

#include <stdio.h>
#include <string.h>
char* getString();

char* getString(){
    char str[10];
    gets(str);
    return str;

}

int main() {

    char* s;
    s=getString();
    strcpy(s,"Hi");
    puts(s);
    return 0;
}

I know that the length of str must be less than 10, but even when I wrote just "Hi", nothing was being printed. as far as I see it, it should be Ok. the compiler says that fgets is dangerous and should not be used.

What is the reason that nothing being printed on the screen?

Numerator
  • 1,389
  • 3
  • 21
  • 40
  • 7
    You're returning a local... Don't do that... :) I'm surprised the compiler isn't giving you a warning for that. – Mysticial Jul 17 '12 at 06:47
  • Related: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – Flexo Jul 17 '12 at 06:50

4 Answers4

6
char str[10];
// ...
return str;

This is wrong!!! Local variables are invalidated when their scope exits; thus using returned array is undefined behavior. You have to malloc a string and return it:

return strdup(str);
  • 1
    When you call function getString it allocates 10 bytes for str in which you gets data from stdin using gets. Now when you return this and gets out of the function, this 10bytes memory pointed by str becomes invalid. So, you should not use it anymore. – jsist Jul 17 '12 at 07:01
  • Do you mean something like that? char* getString() { char* s; s = (char*)malloc(sizeof(char)*10); gets(s); return s; } But s here is also a local variable for this function, isn't it? so it's more because of the memory not being saved? – Numerator Jul 17 '12 at 07:03
  • memory allocated using calloc/malloc is from heap which is accessible/available to program until that memory block is not deallocated – jsist Jul 17 '12 at 07:18
  • @Numerator I was sure somebody was going to ask this. The local variable is a pointer; it **is** invalidated upon return, but since it's a pointer, its value will be, say, copied (to a register, to the stack, etc. depending on the calling convention) and that pointer will still point to the valid, allocated memory address. If this wasn't the case, functions couldn't return primitive types. –  Jul 17 '12 at 10:38
3

Problem pertaining to result have already being discussed. List of solutions that you can do includes:

1). define str globally as "char str[10]" and use it in function main and getString

2). Use malloc/calloc in function getString, code goes something like this...

char* getString(){
char *str = NULL;
str = (char *)calloc(10, sizeof(char));
gets(str);
return str;
}

int main() {
    char* s;
    s=getString();
    strcpy(s,"Hi");
    puts(s);
    free(s);
    return 0;
}`

3). use static for ready help. But it is not conceptually correct approach

e.g. declare as follows in function getString

static char str[10];
jsist
  • 5,223
  • 3
  • 28
  • 43
  • Do you have to initialize str in getString? Doesn't it have a default initialization of "0" (which is equivalent to Null in our case)? – Numerator Jul 17 '12 at 07:17
  • What you are saying is compiler dependent. Some compilers initailizes to zero while some may lead to garbage value. So its always good to initialise to be safe from unpredictable behaviour. – jsist Jul 17 '12 at 07:21
  • sizeof(char), casting the return value from malloc&co, gets and strcpy are all great filters when reading example code in job applications. It would be nice to someone trying to learn to teach them good practices. – Art Jul 17 '12 at 07:49
1

The simplest way of getting your code working, though not necessarily the best way, is to make str static.

i.e.

static char str[10];
acraig5075
  • 10,588
  • 3
  • 31
  • 50
0

Well str[10] is a an array of 10 characters allocated on the stack. The stack is removed after the function is out of scope. Hence the address that was returned by the function getString() is no longer valid.

Consider declaring a pointer char *str and dynamically allocating memory with malloc. Now your variable points to a location in the heap which continues to remain even after the function has finished executing.

Hope it answered your question

Andy Stow Away
  • 649
  • 1
  • 8
  • 17