Incorrect checksum for freed object on malloc - c

I get an
malloc: *** error for object 0x1001012f8: incorrect checksum for freed object
- object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
error in the following function:
char* substr(const char* source, const char* start, const char* end) {
char *path_start, *path_end, *path;
int path_len, needle_len = strlen(start);
path_start = strcasestr(source, start);
if (path_start != NULL) {
path_start += needle_len;
path_end = strcasestr(path_start, end);
path_len = path_end - path_start;
path = malloc(path_len + 1);
strncpy(path, path_start, path_len);
path[path_len] = '\0';
} else {
path = NULL;
}
return path;
}
How can I make this work? When I rewrite the function to allocate the memory using path[path_len + 1] it works just fine.
Now, the part I don't understand is, that I never even call free in any point of my application, as every allocated memory is needed for the program until it exists (which, AFAIK will invalidate every allocated memory anyway?!)
So, how can a freed object be corrupt if I never free one?
The function is called in this one:
char *read_response(int sock) {
int bytes_read;
char *buf = (char*)malloc(BUF_SIZE);
char *cur_position = buf;
while ((bytes_read = read(sock, cur_position, BUF_SIZE)) > 0) {
cur_position += bytes_read;
buf = realloc(buf, sizeof(buf) + BUF_SIZE);
}
int status = atoi(substr(buf, "HTTP/1.0 ", " "));
There is the realloc, am I using that wrong? I want to read the complete server response, so I have to reallocate after every iteration, don't I?

In read_response, you are probably overwriting the end of the buffer pointed to by buf.
The problem is that buf is a pointer, so sizeof(buf) will return the size of a pointer (probably 4 or 8 depending on your CPU). You are using sizeof as if buf were an array, which is not really the same thing as a pointer in C although they seem interchangeable in some contexts.
Instead of using sizeof, you need to be keeping track of the last size that you allocated for buf, and add BUF_SIZE to that each time you enlarge the buffer.
You should also consider that the read operation may be returning considerably fewer characters than BUF_SIZE on each call, so doing a realloc on buf in each iteration may be overkill. That probably won't cause any problems for you in terms of correctness, though; it will just use more memory than it needs to.
I would do something more like the code below.
#define MIN_BUF_SPACE_THRESHOLD (BUF_SIZE / 2)
char *read_response(int sock) {
int bytes_read;
char *buf = (char*)malloc(BUF_SIZE);
int cur_position = 0;
int space_left = BUF_SIZE;
if (buf == NULL) {
exit(1); /* or try to cope with out-of-memory situation */
}
while ((bytes_read = read(sock, buf + cur_position, space_left)) > 0) {
cur_position += bytes_read;
space_left -= bytes_read;
if (space_left < MIN_BUF_SPACE_THRESHOLD) {
buf = realloc(buf, cur_position + space_left + BUF_SIZE);
if (buf == NULL) {
exit(1); /* or try to cope with out-of-memory situation */
}
space_left += BUF_SIZE;
}
}
This version has the advantage of not trying to allocate more space if the read call comes back with only a few bytes of data.

This line
buf = realloc(buf, sizeof(buf) + BUF_SIZE);
is wrong. All reallocations are with the same size, BUF_SIZE + sizeof(char*). Then you are writing to unallocated memory when reading from the socket, overwriting memory previously freed by a realloc.
You have to keep track of the allocated size,
size_t current_buf_size = BUF_SIZE;
/* ... */
char *temp = realloc(buf, current_buf_size + BUF_SIZE);
if (temp == NULL) {
/* die or repair */
}
buf = temp;

Related

Resizing dynamic arrays in c

How do you properly resize an array using realloc so that the newly allocated array can have the data from the previous array plus the newly received data
int receiver (int soc_desc, char * buffer)
{
char *arr;
size_t received =0 , total_received=0;
char buff[MAX+1];
memset(buff , 0 , MAX+1);
while (1)
{
received = recv(soc_desc, buff , MAX , 0 );
if (received <= 0 )
break;
else
{
total_received = total_received + strlen(buff);
buffer = realloc(buffer, total_received);
printf("Total: %ld received: %ld \n",total_received , received);
strcat(buffer, buff);
}
printf("%s\n",buff);
}
printf("Final result: %s \n", buffer);
in this function, we pass a socket descriptor and a char *buffer = malloc(MAX) we receive data and add it to the allocated buffer and then try to reallocate the buffer for the next chunk of data, is there a way to resize the original mallocd buffer so that I can fit more characters in it without creating a new pointer for realloc each time it is called
when I compile and run this code with valgrind I get
==13850== Address 0x4a5c0e3 is 0 bytes after a block of size 3 alloc'd
==13850== at 0x483DFAF: realloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==13850== by 0x109884: ??? (in /home/User/Desktop/test)
==13850== by 0x109476: ??? (in /home/User/Desktop/test)
==13850== by 0x48870B2: (below main) (libc-start.c:308)
.
.
.
.
==13850== HEAP SUMMARY:
==13850== in use at exit: 27 bytes in 1 blocks
==13850== total heap usage: 22 allocs, 22 frees, 15,807 bytes allocated
since buffer is a function parameter I used free(buffer) outside the function
Compile using -g3 -ggdb3 -Wall -Wextra flags to get line number of error in valgrind and other sort of warnings.
Also, realloc() copies previous data to new one.
Some Points:
total_received = total_received + strlen(buff); can be written as total_received += strlen(buff);
You need to take buffer as char **buffer and then de-reference it like (*buffer), so that modification of buffer can be done permanently in another function's scope
"%zu" is valid format specifier for size_t
Make sure that buffer is heap-allocated in its definition scope
memset(buff , 0 , MAX+1); can be written as char buff[MAX+1] = {};
I don't see any use of arr variable in receiver() function
NOTE: Make sure that new size for buffer is larger than the previous size
Always check whether heap allocation was successful or not, by checking the pointer against NULL, eg., if(!buffer) { /* error */ }
Pass buffer like &buffer [give address of buffer to receiver() function]
received is unsigned long int AKA size_t which means it starts from 0, hence checking for less than 0 is not required, instead check for (received == 0)
Use memcpy() to append buff to *buffer by limiting the length of buff
Append null terminating character at the very end of *buffer
Final Code:
int receiver(int soc_desc, char **buffer)
{
char *arr; // idk
size_t received = 0, total_received = 0;
char buff[MAX + 1] = {}; // every element is now 0
while (1)
{
received = recv(soc_desc, buff, MAX, 0);
if (received == 0)
break;
else
{
total_received += received;
(*buffer) = realloc(*buffer, total_received + 1);
if (*buffer == NULL) // error occurred
{
exit(EXIT_FAILURE);
}
printf("Total: %zu received: %zu\n", total_received, received);
memcpy(*buffer, buff, received);
(*buffer)[total_received + 1] = 0; // nul terminating character
}
printf("%s\n", buff);
}
printf("Final result: %s \n", *buffer);
/*your rest of the code */
According to the documentation:
Reallocates the given area of memory. It must be previously allocated by malloc(), calloc() or realloc() and not yet freed with a call to free or realloc. Otherwise, the results are undefined.
The reallocation is done by either:
a) expanding or contracting the existing area pointed to by ptr, if possible. The contents of the area remain unchanged up to the lesser of the new and old sizes. If the area is expanded, the contents of the new part of the array are undefined. (*)
b) allocating a new memory block of size new_size bytes, copying memory area with size equal the lesser of the new and the old sizes, and freeing the old block.
If there is not enough memory, the old memory block is not freed and null pointer is returned. (#)
The formatting (bold text) and (*) and (#) have been added, and were not in the quoted text.
Solving (#):
bool realloc_buffer(void **buffer, size_t new_size)
{
void *tmp = *buffer;
*buffer = realloc(*buffer, new_size);
if (!*buffer) { // Realloc failed: restore the old pointer.
*buffer = tmp;
return false;
}
return true;
}
Then in your code:
int receiver (int soc_desc, char **buffer)
{
// ...
if (!realloc_buffer(buffer, old_size + total_received + 1)) { // You should know the old size
// Handle failure
}
}
You said:
... so that the newly allocated array can have the data from the previous array plus the newly received data
According to (*), you have to manually append the new data.
int receiver (int soc_desc, char **buffer)
{
// ...
char *copy = malloc(sizeof(char*) * (old_size+1));
// Make a copy of the old buffer
memcpy(copy, buffer, old_size+1);
if (!realloc_buffer(buffer, old_size + total_received + 1)) { // You should know the old size
// Handle failure
} else {
memcpy(buffer + old_size * sizeof(char*), copy, total_received+1);
}
free(copy);
// ...
}

Pointer within structure reallocs fine, but pointer to a pointer within structure fails to realloc with invalid pointer error

While working on a program which requires frequent memory allocation I came across behaviour I cannot explain. I've implemented a work around but I am curious to why my previous implementation didn't work. Here's the situation:
Memory reallocation of a pointer works
This may not be best practice (and if so please let me knwow) but I recall that realloc can allocate new memory if the pointer passed in is NULL. Below is an example where I read file data into a temporary buffer, then allocate appropriate size for *data and memcopy content
I have a file structure like so
typedef struct _my_file {
int size;
char *data;
}
And the mem reallocation and copy code like so:
// cycle through decompressed file until end is reached
while ((read_size = gzread(fh, buf, sizeof(buf))) != 0 && read_size != -1) {
// allocate/reallocate memory to fit newly read buffer
if ((tmp_data = realloc(file->data, sizeof(char *)*(file->size+read_size))) == (char *)NULL) {
printf("Memory reallocation error for requested size %d.\n", file->size+read_size);
// if memory was previous allocated but realloc failed this time, free memory!
if (file->size > 0)
free(file->data);
return FH_REALLOC_ERROR;
}
// update pointer to potentially new address (man realloc)
file->data = tmp_data;
// copy data from temporary buffer
memcpy(file->data + file->size, buf, read_size);
// update total read file size
file->size += read_size;
}
Memory reallocation of pointer to pointer fails
However, here is where I'm confused. Using the same thought that reallocation of a NULL pointer will allocate new memory, I parse a string of arguments and for each argument I allocate a pointer to a pointer, then allocate a pointer that is pointed by that pointer to a pointer. Maybe code is easier to explain:
This is the structure:
typedef struct _arguments {
unsigned short int options; // options bitmap
char **regexes; // array of regexes
unsigned int nregexes; // number of regexes
char *logmatch; // log file match pattern
unsigned int limit; // log match limit
char *argv0; // executable name
} arguments;
And the memory allocation code:
int i = 0;
int len;
char **tmp;
while (strcmp(argv[i+regindex], "-logs") != 0) {
len = strlen(argv[i+regindex]);
if((tmp = realloc(args->regexes, sizeof(char **)*(i+1))) == (char **)NULL) {
printf("Cannot allocate memory for regex patterns array.\n");
return -1;
}
args->regexes = tmp;
tmp = NULL;
if((args->regexes[i] = (char *)malloc(sizeof(char *)*(len+1))) == (char *)NULL) {
printf("Cannot allocate memory for regex pattern.\n");
return -1;
}
strcpy(args->regexes[i], argv[i+regindex]);
i++;
}
When I compile and run this I get a run time error "realloc: invalid pointer "
I must be missing something obvious but after not accomplishing much trying to debug and searching for solutions online for 5 hours now, I just ran two loops, one counts the numbers of arguments and mallocs enough space for it, and the second loop allocates space for the arguments and strcpys it.
Any explanation to this behaviour is much appreciated! I really am curious to know why.
First fragment:
// cycle through decompressed file until end is reached
while (1) {
char **tmp_data;
read_size = gzread(fh, buf, sizeof buf);
if (read_size <= 0) break;
// allocate/reallocate memory to fit newly read buffer
tmp_data = realloc(file->data, (file->size+read_size) * sizeof *tmp_data );
if ( !tmp_data ) {
printf("Memory reallocation error for requested size %d.\n"
, file->size+read_size);
if (file->data) {
free(file->data)
file->data = NULL;
file->size = 0;
}
return FH_REALLOC_ERROR;
}
file->data = tmp_data;
// copy data from temporary buffer
memcpy(file->data + file->size, buf, read_size);
// update total read file size
file->size += read_size;
}
Second fragment:
unsigned i; // BTW this variable is already present as args->nregexes;
for(i =0; strcmp(argv[i+regindex], "-logs"); i++) {
char **tmp;
tmp = realloc(args->regexes, (i+1) * sizeof *tmp );
if (!tmp) {
printf("Cannot allocate memory for regex patterns array.\n");
return -1;
}
args->regexes = tmp;
args->regexes[i] = strdup( argv[i+regindex] );
if ( !args->regexes[i] ) {
printf("Cannot allocate memory for regex pattern.\n");
return -1;
}
...
return 0;
}
A few notes:
the syntax ptr = malloc ( CNT * sizeof *ptr); is more robust than the sizeof(type) variant.
strdup() does exactly the same as your malloc+strcpy()
the for(;;) loop is less error prone than a while() loop with a loose i++; at the end of the loop body. (it also makes clear that the loopcondition is never checked)
to me if ( !ptr ) {} is easyer to read than if (ptr != NULL) {}
the casts are not needed and sometimes unwanted.

returned value from realloc() give a segmentation fault

#define BUF_SIZE 10
char *html = "foo:baa\r\nxxx:yyyy:\r\nLocation:........................................\r\Connection:close\r\n\r\n";
char *p = (char*)html, *buf, *pbuf, *tbuf;
int buf_size = BUF_SIZE, hsize = 0;
if((buf = malloc(buf_size)) == NULL) FAILED("NO MEMORY!\n");
pbuf = buf;
while(*p != '\0' && *(p + 1) != '\r' && *(p + 2) != '\n') {
if((hsize + 1) >= buf_size) {
printf("Do realloc!\n");
buf_size += BUF_SIZE + 2;
tbuf = realloc(buf, buf_size); // BUF_SIZE
if(tbuf != NULL) {
buf = tbuf;
} else {
printf(" NO MEMORY!\n");
exit(1);
}
}
*pbuf ++= *p++, hsize ++;
}
But it give an
Do realloc!
Do realloc!
Stack trace:
Frame Function Args
0022A814 7798EFA3 (000000FC, 0000EA60, 00000000, 0022A948)
0022A828 7798EF52 (000000FC, 0000EA60, 000000A4, 0022A924)
0022A948 610DB059 (00000000, 00000001, 0022A978, 0000000C)
0022AA38 610D841E (00000000, 61102908, 003B0023, 00230000)
0022AA98 610D88EE (20038878, 0000000C, 0022AAC8, 00000006)
0022AB48 610D8A40 (00000E3C, 00000006, 00000001, 20010340)
0022AB68 610D8A6C (00000006, 0022CE80, 0022ABD4, 20038883)
0022AB98 610D8CF5 (004031AA, 20010340, 0022ABE8, 61138596)
20010348 6110F935 (73756A2E, DF0DF02E, 200000C8, 00000000)
I have no idea how to fix this! Actually, I am not sure that it's a really segmentation fault.
You have two fatal issues:
pbuf is assigned the value of buf at init but then is never updated. realloc is not guaranted to return the same address after malloc (and the subsequent realloc calls).
You are overflowing pbuf here before calling the required realloc:
*pbuf ++= *p++, hsize ++;
*pbuf ++= *p++, hsize ++;
You never initialize pBuf. Also:
tbuf = realloc(buf, BUF_SIZE);
Should be:
tbuf = realloc(buf, buf_size);
EDIT:
As #ouah noted in the comments, and considering that you do in fact initialize pBuf (though we can't see it), it seems that the way in which you manipulate p is the likely culprit. What is the type and contents of html? Is it null terminated? Are any of your *(p + n) expressions overruning it's valid bounds?
You are using the #define version of BUF_SIZE.
realloc(buf, BUF_SIZE);
You should use the computed value that is stored in buf_size.
realloc(buf, buf_size);
I haven't looked at your code exhaustively, but do you really mean to be calling realloc() with BUF_SIZE (which is a fixed preprocessor constant), rather than buf_size? It's generally not good practice to have symbols with different values and purposes which differ only by case (partially because of these sorts of errors).
You are re-calculating buf_size, but you are not using it in realloc. I think it should be
tbuf = realloc(buf, buf_size); // not BUF_SIZE
Currently, you keep re-allocating at size 10.
In addition to the many bugs mentioned in the many other answers: After you call realloc, pbuf is no longer valid, yet you dereference it.

C - Unable to free allocated memory

I have a problem with an application I'm currently developing. In this program I have to read huge amounts (billions) of data from text files and manage them consequently, but since it's a two students project, the reading part will be developed by my mate. For testing reason I wrote a small procedures that generates pseudo-random structures to replace what my mate will do.
The problem is the following: a big amount of the generated data (due to redundancy) can be discarded in order to free its memory. But even invoking the free() function the memory usage keeps growing. So I tried to develop a debug application that simply generates a chunk of data and immediately frees it. And repeats that for thousands of times. Well, I can't grasp the reason, but the memory allocated to the process grows to ~1.8 GB ram and then crashes. Why? The strangest thing, that makes me thing there's a lot I'm not understanding well, is that when the process crashes the malloc does NOT return a NULL pointer, because the process always crashes when readCycles == 6008 and bypasses the NULL check.
I already read other related topics here on StackOverflow and I understood why free() doesn't reduce the memory allocated to my process. That's fine. But why the memory usage keeps growing? Shouldn't the malloc allocate previously freed memory instead of constantly requesting new one?
This is the most relevant part of my code:
#define NREAD 1000
#define READCYCLES 10000
#define N_ALPHA_ILLUMINA 7
#define N_ALPHA_SOLID 5
#define SEQLEN 76
typedef struct{
char* leftDNA;
char* leftQuality;
unsigned long int leftRow;
char* rightDNA;
char* rightQuality;
unsigned long int rightRow;
} MatePair;
unsigned long int readCycles = 0;
MatePair* readStream(MatePair* inputStream, short* eof, unsigned long int* inputSize){
double r;
unsigned long int i, j;
unsigned long int leftRow;
int alphabet[] = {'A', 'C', 'G', 'T', 'N'};
inputStream = (MatePair*) malloc (sizeof(MatePair) * (NREAD + 1));
printf("%d\n", readCycles);
if (inputStream == NULL){
(*eof) = 1;
return;
}
for (i = 0; i < NREAD; i++){
leftRow = readCycles * NREAD + i;
inputStream[i].leftDNA = (char*) malloc (SEQLEN);
inputStream[i].rightDNA = (char*) malloc (SEQLEN);
inputStream[i].leftQuality = (char*) malloc (SEQLEN);
inputStream[i].rightQuality = (char*) malloc (SEQLEN);
for (j = 0; j < SEQLEN; j++){
r = rand() / (RAND_MAX + 1);
inputStream[i].leftDNA[j] = alphabet[(int)(r * 5)];
inputStream[i].rightDNA[j] = alphabet[(int)(r * 5)];
inputStream[i].leftQuality[j] = (char) 64 + (int)(r * 60);
inputStream[i].rightQuality[j] = (char) 64 + (int)(r * 60);
}
inputStream[i].leftDNA[SEQLEN - 1] = '\0';
inputStream[i].rightDNA[SEQLEN - 1] = '\0';
inputStream[i].leftQuality[SEQLEN - 1] = '\0';
inputStream[i].rightQuality[SEQLEN - 1] = '\0';
inputStream[i].leftRow = leftRow;
inputStream[i].rightRow = leftRow;
}
inputStream[i].leftRow = -1;
readCycles++;
(*inputSize) = NREAD;
(*eof) = readCycles > READCYCLES;
return inputStream;
}
int main(int argc, char* argv[]){
short eof = 0;
unsigned long int inputSize = 0;
MatePair* inputStream = NULL;
while (!eof){
inputStream = readStream(inputStream, &eof, &inputSize);
free(inputStream);
inputStream = NULL;
}
return 0;
}
I forgot to mention that, but before posting here, instead of calling free(inputStream), I tried invoking freeMemory(inputStream). Not sure if it's the correct way of doing it, though.
void freeMemory(MatePair* memblock){
for ( ; memblock->leftRow != 1; memblock++){
free(memblock -> leftDNA);
free(memblock -> leftQuality);
free(memblock -> rightDNA);
free(memblock -> rightQuality);
}
}
Memory leaks. How many 'malloc()' you have called, how many 'free()' you must use to free all allocated memory on the heap.
Thus,
inputStream[i].leftDNA = (char*) malloc (SEQLEN);
inputStream[i].rightDNA = (char*) malloc (SEQLEN);
inputStream[i].leftQuality = (char*) malloc (SEQLEN);
inputStream[i].rightQuality = (char*) malloc (SEQLEN);
these 'malloc()' functions must be paired with free().
You're not freeing all members allocated within the read loop, hence you're losing memory eahc time. Remember, you have to free everything you allocate with a malloc, not just your array.
Ok, Just look at your edit, and your freeMemory is still wrong. Try this;
void freeMemory(MatePair* inputStream)
{
for (i = 0; i < NREAD; i++){
free(inputStream[i].leftDNA);
free(inputStream[i].leftQuality);
free(inputStream[i].rightDNA);
free(inputStream[i].rightQuality);
}
free (inputStream);
}
Your free(memblock) was in the loop, which it shouldn't have been, and I'd tend to use the same iteration sequence on freeing as mallocing. You also need to error check after each malloc, and decide what to do with a NULL at that point.

C string append

I'm looking for an efficient method for appending multiple strings.
The way it should work is C++ std::string::append or JAVA StringBuffer.append.
I wrote a function which actually reallocs previous source pointer and does strcat.
I believe this is not an efficient method as compiler may implement this free and malloc.
Other way I could think of (like std::vector) is allocate memory in bulk (1KB for eg) and do strcpy. In that case every append call will check if the total required allocation is more than (1200 bytes) the amount allocated in bulk, realloc to 2KB. But in that case there will be some memory wasted.
I'm looking for a balance between the above but the preference is performance.
What other approaches are possible. Please suggest.
I would add each string to a list, and add the length of each new string to a running total. Then, when you're done, allocate space for that total, walk the list and strcpy each string to the newly allocated space.
The classical approach is to double the buffer every time it is too small.
Start out with a "reasonable" buffer, so you don't need to do realloc()s for sizes 1, 2, 4, 8, 16 which are going to be hit by a large number of your strings.
Starting out at 1024 bytes means you will have one realloc() if you hit 2048, a second if you hit 4096, and so on. If rampant memory consumption scares you, cap the growth rate once it hits something suitably big, like 65536 bytes or whatever, it depends on your data and memory tolerance.
Also make sure you buffer the current length, so you can do strcpy() without having to walk the string to find the length, first.
Sample function to concatenate strings
void
addToBuffer(char **content, char *buf) {
int textlen, oldtextlen;
textlen = strlen(buf);
if (*content == NULL)
oldtextlen = 0;
else
oldtextlen = strlen(*content);
*content = (char *) realloc( (void *) *content, (sizeof(char)) * (oldtextlen+textlen+1));
if ( oldtextlen != 0 ) {
strncpy(*content + oldtextlen, buf, textlen + 1);
} else {
strncpy(*content, buf, textlen + 1);
}
}
int main(void) {
char *content = NULL;
addToBuffer(&content, "test");
addToBuffer(&content, "test1");
}
I would do something like this:
typedef struct Stringbuffer {
int capacity; /* Maximum capacity. */
int length; /* Current length (excluding null terminator). */
char* characters; /* Pointer to characters. */
} Stringbuffer;
BOOL StringBuffer_init(Stringbuffer* buffer) {
buffer->capacity = 0;
buffer->length = 0;
buffer->characters = NULL;
}
void StringBuffer_del(Stringbuffer* buffer) {
if (!buffer)
return;
free(buffer->characters);
buffer->capacity = 0;
buffer->length = 0;
buffer->characters = NULL;
}
BOOL StringBuffer_add(Stringbuffer* buffer, char* string) {
int len;
int new_length;
if (!buffer)
return FALSE;
len = string ? strlen(string) : 0;
if (len == 0)
return TRUE;
new_length = buffer->length + len;
if (new_length >= new_capacity) {
int new_capacity;
new_capacity = buffer->capacity;
if (new_capacity == 0)
new_capacity = 16;
while (new_length >= new_capacity)
new_capacity *= 2;
new_characters = (char*)realloc(buffer->characters, new_capacity);
if (!new_characters)
return FALSE;
buffer->capacity = new_capacity;
buffer->characters = new_characters;
}
memmove(buffer->characters + buffer->length, string, len);
buffer->length = new_length;
buffer->characters[buffer->length] = '\0';
return TRUE;
}

Resources