5

I am working on some kind of file sharing program which is written in C. There is a function that can read a data file and store the data into a string and return this string to main function and the main function send back to client. Codes are shown below

char* ListFiles(){
    FILE *fp;
    char file[30];
    char *f;
    if((fp=fopen("list","r"))==NULL)  
    {
        ...
    }
    while (!feof(fp))
    {
        fgets(file,50,fp);
    }
    fclose(fp);
    f=file;
    printf("%s",f); //get display!!!
    return f;
}
int main(){
      char *files;
      ...
      ...
      files=ListFiles();
      printf("%s",files); //nothing display!!
      sent();
}

However, this method doesn't work. There is nothing display and of course nothing is sent. But I do get the correct display in function ListFiles(). I don't know what happen. I also use strcpy() and it still fail to work.

4
  • 1
    char file[30]; char *f; f = file; nothing good happens here. Think a second about it and write it properly. Commented Apr 12, 2012 at 20:43
  • 2
    This is unrelated, but your file variable can only hold 30 characters and you're reading more than that. file will overflow. Commented Apr 12, 2012 at 20:47
  • 1
    In addition, the fgets will be called repeatedly with the same buffer until the file reaches its end, so that after the loop the buffer will contain only the last part of the file. Commented Apr 12, 2012 at 20:51
  • Here a good example on how to do different things with strings and pointers in C stackoverflow.com/a/46344713/5842403 Commented Sep 22, 2017 at 8:55

6 Answers 6

11

Follow George Skoptsov recommendations. But If you don't have the strdup() function,then use this:

char* strdup(const char* org)
{
    if(org == NULL) return NULL;

    char* newstr = malloc(strlen(org)+1);
    char* p;

    if(newstr == NULL) return NULL;

    p = newstr;

    while(*org) *p++ = *org++; /* copy the string. */
    return newstr;
}

And then:

#include <string.h> /* strlen() call */
#include <stdlib.h> /* NULL, malloc() and free() call */

/* do something... */

char* ListFiles() {
        /* .... */ 
         return strdup(f);
}

Or instead of char file[30]; do a dynamic memory allocation: char* file = malloc(30); then you can do return f; and it will work fine because f now is not a pointer to a local variable.

Sign up to request clarification or add additional context in comments.

2 Comments

Even if you don't have strdup, you always have strcpy when including <string.h>...
Here a good example on how to do different things with strings and pointers in C stackoverflow.com/a/46344713/5842403
11

What you're doing is returning a pointer to a local variable, which used to be allocated on stack.

Change your return statement to

return strdup(file);

2 Comments

strdup is not a standard function, it's only defined in MSVC.
@MrLister: It's available in POSIX environment as well.
4

file is a stack variable in ListFiles() and you're returning a pointer to it. Once you return from that function, the variable will cease to exist, so the returned pointer will be invalid.

If you want to return a string, you should allocate it on the heap, return it, use it, then free it once you're done using it.

Comments

2

You are returning a pointer points to the stack variable. When the function returns, the stack gets popped off. The stack variable no longer exists, the pointer become a dangling pointer.

One solution is to allocate the appropriate amount of memory in the main function, and pass the pointer to the memory to the helper function.

Comments

0

you shouldn't return data that sits on automatic storage, when you return it goes out of scope.

1 Comment

scope and storage duration are two different beasts.
0

You're trying to display a string value char file[30] that is allocated on the stack (function stack). The content of this memory is not guaranteed after the method return. You should allocate it dynamically (for ex. malloc) or eventually use global value, or allocate it on the stack of the outer function (in your example main() function)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.