0

function returns address of local variabe

const char * read() {
    FILE *fp;
    char buff[256];
    fp = fopen("/sys/class/net/enp1s0/statistics/rx_bytes", "r");
    fgets(buff, 256, (FILE*)fp);
    fclose(fp);
    return buff;
}

int main(){
    const char* server_message = read(); //returns null here
}

The question is: how to assign the buuf's value to server_message variable

Thanks

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • The comment is incorrect, as the `read` function does not return null. Rather, it returns an invalid address. If you want to return a valid address, you should allocate space for buff. – William Pursell Mar 20 '20 at 16:04
  • 1
    Welcome to SO. I doubt that the function returns `NULL`. Instead an address is returned that is illegal to access after the function returns. – Gerhardh Mar 20 '20 at 16:04
  • I agree with @Gerhardh. Old style library functions would make the `buff` variable static, but that's considered bad style for a number of reasons. Or you allocate the result dynamically and the caller has to free it. – Hellmar Becker Mar 20 '20 at 16:08
  • So, please, could you explain how can I access this string inside my main function. Thanks – catfishomeex Mar 20 '20 at 16:08
  • In other words, the memory for `char buff[256]` is only local and available inside of the function `read`. The memory is deallocated at the end of the function, so when you return it, it ends up as undefined behaviour. – DeiDei Mar 20 '20 at 16:08
  • See https://stackoverflow.com/questions/1496313/returning-c-string-from-a-function and the top answer in particular – neutrino_logic Mar 20 '20 at 16:08

2 Answers2

1

You need to provide the memory for the string. If you do this inside the called function like shown, it will be an automatic variable that is de-allocated on return.

So better do this:

void read(char buff[], size_t size) {
    FILE *fp;
    fp = fopen("/sys/class/net/enp1s0/statistics/rx_bytes", "r");
    fgets(buff, size, (FILE*)fp);
    fclose(fp);
}

int main(){
    char server_message[256] = "";
    read(server_message, sizeof server_message - 1);
}
the busybee
  • 10,755
  • 3
  • 13
  • 30
0

If you had to determine the amount of memory to allocate to the string in the function, perhaps after scanning the file, you'd have to do something like this, which is more like your original code:

int read(char** buff) {                //has to be pointer-to-pointer
    FILE *fp;
    size_t file_size = 256;
    *buff = malloc(file_size * sizeof(char));             //dynamic memory allocation
                                                          //fail checks are a good idea
    fp = fopen("/sys/class/net/enp1s0/statistics/rx_bytes", "r");
    fgets(*buff, file_size, (FILE*)fp);
    fclose(fp);
    return file_size;                 
}

int main() {
    char* server_message = NULL;
    size_t size = read(&server_message);       //pass address of server_message to func
    ///...do something
    free(server_message);                      //deallocate borrowed memory
    server_message = NULL;                     //eliminate dangling pointer
}
neutrino_logic
  • 1,289
  • 1
  • 6
  • 11
  • Please, explain me how can i get the value of file fp in the string inside main function, including such condition that this value need to be stored only inside this file. In other words how can I pass from local to local variables in different functions in c. Thank you for attention – catfishomeex Mar 20 '20 at 17:06
  • @catfishomeex You want to open the file in one function, read the contents of that file into a single string (locally created inside that function), close the file, and pass the string onto another function? That involves passing from one local array to another local array. To do this safely, you generally have to pass a pointer to an array from one function to the other, then use that pointer to copy (char by char) from the local array to the the memory that's 'local' to the calling function. – neutrino_logic Mar 20 '20 at 18:07