Why is realloc only copying part of the data? [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
So I ran into an issue where it seemed like realloc wasn't copying all of the data in a buffer so I decided to run the following code as a test.
#include <stdlib.h>
int main(int argc, char** argv)
{
int* tmp_array = malloc(sizeof(int) * 2);
tmp_array[0] = 1;
tmp_array[1] = 2;
tmp_array = realloc(tmp_array, 4);
return 0;
}
The same issue I originally had was still happening, only part of the data is being copied. The 1 in the buffer gets copied, however the 2 does not. I am allocating enough space for 2 integers at first so both if the assignments to tmp_array should be valid. Then reallocating to 4 seems valid. I even tried explicitly casting the returned realloc pointer to int* but that didn't help.
Unfortunately, I can't show the screenshots of my memory window in the debugger (VS 2017) but it definitely shows the 1 and 2 in the buffer before realloc and only shows the 1 in the buffer after the realloc.
I'm sure I could reimplement realloc myself by just using malloc and memcpy to copy the data over manually, but I still just want to know why this isn't working.
Any help is greatly appreciated!

You are reallocating to 4 bytes, not to 4*sizeof(int), which incidentally copies just first int (and discards other).
realloc, as malloc, works on bytes so you must use them both in the same way.

Related

Hanging program after trying to free allocated memory [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I'm not quite sure what is wrong with my current program and I have reach a bit of a road block:
(*ptr).Name = (char*)malloc(strlen(record+1));
strcpy((*ptr).Name, record);
free((*ptr).Name); //problem area
*ptr is a pointer that points to a structure that has various fields. After I copy some data into the Name field I want to free my allocated memory. When I step through my program I get no errors rather just a hanging program that will not continue after I try and free the memory. Any ideas? Thank you.
(*ptr).Name = (char*)malloc(strlen(record+1)); //This is the problem!
strcpy((*ptr).Name, record);
free((*ptr).Name); //problem area //Better practice to use free(ptr->Name
Fix:
ptr->Name = (char*)malloc(strlen(record)+1); //(record+1) in previouse code was doing
//the opposite of what it was intended to do
strcpy(ptr->Name, record);
free(ptr->Name);

How to prevent undefined behavior, from a user/new developer perspective? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
So the question is, how does the original developer prevent a situation where user/new developer is trying to access a free'd memory element.
int *num=(int *)malloc(n*sizeof(int));
int i;
for(i=0;i<n;i++)
{
scanf("%d",&num[i]);
}
for(i=0;i<n-1;i++){
temp = some_function(x);
}
free(num);
for(i=0;i<n;i++)
{
printf("\nnum[%d]= %d\n",i,num[i]);
}
P.S.: The above code works and actually prints out data in array. Which is not our intention.
[EDIT] Sorry if I was not clear enough. Someone suggested to ask this as a separate question, I thought why not. Here's the original post
The fact that your code "works" is a manifestation of the undefined behaviour that you're experiencing when reading memory that you no longer own.
You could consider setting num to NULL after the first free call. Then writing num[i] will almost certainly crash the program. It can also occasionally be useful: a free called with NULL passed as the pointer is a no-op.
There's little else you can do unfortunately.
But, in general, setting freed pointers to NULL leads to sloppy programming so I tend to avoid it.
The first thing you can do is set num=NULL.
More generally you can add a malloc hook to write garbage to the memory before freeing the memory (probably debug only). This will force a crash if the memory contains pointers or print garbage in this case when accessing freed memory.
Also since you are talking C++, make use of smart pointers.
Edit: fixed up the crash issue.

What happens when you switch parameters when calling calloc function? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I've spent quite a moment today trying to figure out why a super-simple C function, which reads a text file, doesn't work. I was able to make it work by swapping parameters in calloc function:
Instead of:
calloc(1, size_of_the_memory_to_allocate)
I did:
calloc(size_of_the_memory_to_allocate, 1)
So instead of 1 element of size 20, I did 20 of size 1.
calloc(size, 1)
Is there any difference in the allocation?
EDIT2:
I guess I was not clear enough with the question, or it was misunderstood. The question was: "Why allocating pointer to pointer using calloc requires swapping arguments?". It wasn't about debugging the code, nor have I asked anyone to run it, it was about how calloc works. The answer made by #chqrlie is exactly what I was looking for. I guess I have made a mistake of adding any code to the question, and readers concentrated on it, rather than on what I have asked for. So, here's an edit, and now chqrlie's answer fit perfectly. If this still is something that won't help other users, let's just delete the question and be done with it.
The prototypes for calloc and fread are:
void *calloc(size_t nmemb, size_t size);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
The order of arguments is indeed inconsistent between these standard C library functions. It is unfortunate but it has been like this for close to 40 years and cannot be changed now.
Note that if you swap the arguments in calloc, you should get exactly the same behavior, but it is not the case for fread that returns the number of elements completely read.
The behavior you describe in your updated question is highly surprising. Either there is something you are not telling us, or your C library implements a non standard constraint in calloc() that ends up backfiring into a bug.
Note that calloc(nmemb, size) cannot just call malloc(nmemb * size) because of potential arithmetic overflow, which in the case of size_t arguments is defined in the standard. For example calloc(-1, -1) must fail, but instead would return malloc(1) if naively calling malloc(nmemb * size). The test for this overflow might be buggy in such a way as to fail for calloc(1, size) and not for calloc(size, 1) with a large size.

Using Array of Pointer in C++ [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I coded like that, but it gets seg-fault.
What is wrong?
int vector_size = 100000000;
float *rows[vector_size];
for (int i=0; i<vector_size; i++) {
rows[i] = (float *)malloc(sizeof(float)*2); // crashed here
// ...
}
You are trying to allocate a vast amount of memory. If you really need this many floats, using a separate malloc for each one is probably a bad plan. Malloc has it's own overheads as there is a minimum block size that can be allocated, and the memory manager also needs to keep track of all those separately allocated areas of memory, not to mention the size of this list of pointers you are holding.
A better solution might be to allocate in a single block enough space for all floats, and the index as an array, rather then try and keep a list of pointers...
So...
float *rows = malloc(sizeof(float) * vector_size);
might be a better starting point.
Try to allocate memory not in the stack, but in a heap.
float **rows = new float*[vector_size];
And what message you get about crash?
It don't look like memory overflow, because if memory is ended malloc() returns NULL:\
P.S. sorry for my english)
upd. oh, i don't saw comments above

Segmentation fault error when compiler with one gcc compiler but not with other gcc compilers [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am running into a segmentation fault error in my code and I am not sure what may be causing it. What is even more odd is that when I run I compile/run in gcc-4.4.6 RH6 I obtain no error, but on other compilers/linux distros I get a segmentation fault error.
Here is a snippet of the part of the code that I think may be generating the issue:
int BIN_SIZE=(2*width)/bins;
//binCounts and binCounts2 store the fragment counts in each bin. mask=1 flags histone modification site
float **binVals;
binVals = (float **)malloc(chromNum*sizeof(int *));
//Initialize the arrays
totalBinNum = 0;
for (i=0;i<chromNum;i++)
{
totalBinNum += chromInfo[i].chromSize/BIN_SIZE+1;
binVals[i] = (float *)malloc((chromInfo[i].chromSize/BIN_SIZE+1)*sizeof(float));
memset(binVals[i], 0, (chromInfo[i].chromSize/BIN_SIZE+1)*sizeof(float));
}
If you know some easy catch on what may be causing the error please let me know? Otherwise it could also be in some other part of the code leading to not a smart Q :(
It would be more precise to do so:
binVals = malloc(chromNum*sizeof(float *));
But it is not likely that this is the cause of the error, as you can expect that 2 pointers, even if to different types int* and float*, will have the same size. In short, the source of the error is probably somewhere else in your code.
Some other suggestions:
I would suggest removing the other type cast in the other malloc.
I would use some temporary variable to store chromInfo[i].chromSize/BIN_SIZE+1, so that you do not have to repeat the expression 3 times with very likely cut and past errors.
You can compact the malloc and the memset to zero in one calloc call.

Resources