Search code examples
crealloc

pointer being realloc'd was not allocated


size_t writeFunctionHandler(char *contents,size_t size,size_t nmemb,void *userdata) {
  // size of the storedSize
  static size_t storedSize = 0;

  // the size of data available
  size_t realSize = size * nmemb;

  char *dataBuffer = (char *) userdata;

  // realloc the buffer buffer
  dataBuffer = realloc(dataBuffer,storedSize + realSize);

  if (dataBuffer == NULL) {
    printf("Could not allocate memory \n");
    return 0;
  }

  // store the contents of realSize from last storedSize
  memcpy(&(dataBuffer[storedSize]),contents,realSize);

  storedSize += realSize;
  return realSize;
}

I fail to understand as to why the above code return and error pointer being realloc'd was not allocated

And when I used this sample code

struct MemoryStruct {
  char *memory;
};

size_t writeFunctionHandler(char *contents,size_t size,size_t nmemb, void *userdata) {
  size_t realSize = size * nmemb;
  static size_t storedSize = 0;
  //char *dataBuffer = (char *)userdata;
  struct MemoryStruct *chunk = (struct MemoryStruct *)userdata;

  printf("print 1\n");
  chunk -> memory = realloc(chunk -> memory,storedSize + realSize);
  printf("print 2\n");

  if (chunk -> memory == NULL) {
    printf("Could not allocate memory\n");
    return 0;
  }

  memcpy(&(chunk -> memory[storedSize]),contents,realSize);
  storedSize += realSize;
  printf("print 3\n");

  return realSize;
}

All seem to work properly fine.

This above is a curl writeFunctionHandler

int main() {
   char *buffer = calloc(1,1);
   // struct MemoryStruct chunk;
   // chunk.memory = calloc(1,1);

   CURL *curl = curl_easy_init();

   curl_easy_setopt(curl, CURLOPT_URL, "http://stackoverflow.com");
   curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunctionHandler);
   curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)buffer);
   // curl_easy_setopt(curl,CURLOPT_WRITEDATA, (void *) &chunk);

   free(buffer);
   //free(chunk.memory);
   curl_easy_cleanup(curl);

   return 0;
}

I fail to understand what difference between the 2 code except the fact that I'm using struct in the later case.


Solution

  • The point is that userdata points to struct containing a member memory and it is that member that is alloced from the heap.

    Further, when the function returns, then memory may have been changed with the realloc, but in your version the change cannot be seen outside the function. That is because the value of the pointer was passed, not the address. If the address were passed (i.e. void **userdata), you would have realloced to that address (i.e. *userdata= realloc(..) and it would have become visible outside the function.