Thread: Another question about `warning:address of local variable returned`

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    66

    Another question about `warning:address of local variable returned`

    Hi.

    I know that this warning was subject of many topics here, but i have a question about the solution for that.

    Let`s say I have a function which reads data from a socket (just example).
    I did read, that the best way to avoid returning a local variable is to pass a char pointer to the function in which the data will be stored.

    But in your oppinion, where exactly should I allocate the necessary memory for this variable.

    Should I allocate the memory before I pass the variable to the function (but in this case, i don`t know how many bytes long is the received data. I can write a function which returns the size of the data, but this means that i have to cycle two times through the data), or to pass a null pointer to the function, and use realloc internally?

    The only problem is, that as I know, realloc doesn`t return all the time the same pointer, so this can be an error source.


    What do you think?


    Thanks.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Code:
    char *my_function()
      { char buffer[LONGER_THAN_NEEDED] = {0};
         int   length = 0;
         receivefromsocket(buffer, &length);
         if (length)
           return strdup(buffer);
         else
           return null;  
       }
    
    
    // call like this
    char *text = NULL;
    
    text = MyFunction();
    
    // do whatever
    
    free(text);

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    strdup is fine, so long as you only have textual data that is null terminated. If you have binary data that may contain zero-valued bytes, look you will need to allocate and memcpy. Also, you can expand Tater's suggestion to include a loop using your read function and realloc to grow the buffer as necessary.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by anduril462 View Post
    strdup is fine, so long as you only have textual data that is null terminated. If you have binary data that may contain zero-valued bytes, look you will need to allocate and memcpy. Also, you can expand Tater's suggestion to include a loop using your read function and realloc to grow the buffer as necessary.
    Making the solution look like this...
    Code:
    unsigned char *my_function()
      { unsigned char buffer[LONGER_THAN_NEEDED] = {0};
         int   length = 0;
         receivefromsocket(buffer, &length);
         if (length)
           { unsigned char *data = malloc(length);
              return memcpy(data,buffer,length); }
         else
           return NULL;  
       }
    
    
    // call like this
    unsigned char *data = NULL;
    
    data = MyFunction();
    
    // do whatever
    
    free(data);

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by raczzoli View Post
    Should I allocate the memory before I pass the variable to the function
    I find it easier not to do so, because if you use that function a lot (eg, a "slurp text file" function), you will have to do this all the time:

    Code:
    char *data = malloc(bufsz);
    slurpTextFile(path, data, bufsz);
    Whereas if you make the allocation internal:

    Code:
    char *data = slurpTextFile(path);
    use realloc internally?
    Yes, use a loop like:

    Code:
    #define CHUNK_SZ 1024
    
    int total, cur, chunks, check;
    char *data = malloc(CHUNK_SZ+1), *test;
    [ ...error check *data...]
    cur = total = 0;
    chunks = 1;
    while ((check = read(fd, &data[total], CHUNK_SZ - cur)) {
         if (check == -1)  [ ...handle error...]
         total += check;
         if (check < CHUNK_SZ) {
         // possible partial read, so try once more...
              cur += check;
              continue;
         }
         chunks++;
         cur = 0;
         test = realloc(data, chunks*CHUNK_SZ+1);
         if (!test) {
                free(data);  // give mem back to system
                [...return error...]
         }   
         data = test;
    }
    data[total] = '\0';
    return data;
    So that reads data into a 1kB buffer. If that is not enough, we add another 1kB via realloc and so on. Another algorithm for this is to multiply the buffer size by 2 each time, starting fairly small. The first (linear) version is better when you know the amount of data is always going to be in a certain range. The second (power of two) version is better when the amount of data can vary from tiny to huge.

    For binary data, you can do without adding the null terminator at the end and the extra byte to hold it in the allocation (and probably use an unsigned char* for the buffer).
    Last edited by MK27; 07-11-2011 at 10:58 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 08-14-2009, 03:15 AM
  2. Local variable Question
    By WDT in forum C# Programming
    Replies: 2
    Last Post: 04-02-2009, 05:39 PM
  3. Returning the Address of a Local Variable (Array)
    By Jesdisciple in forum C Programming
    Replies: 9
    Last Post: 08-20-2008, 02:03 AM
  4. Error - function returns address of local variable
    By tltying in forum C Programming
    Replies: 5
    Last Post: 05-28-2007, 02:26 AM
  5. uninitialized local variable question
    By raist in forum C++ Programming
    Replies: 5
    Last Post: 12-02-2006, 03:00 PM