Freeing realloc causing error - c

I am trying to free my memory allocated in the following program:
include <stdio.h>
#include <stdlib.h>
void main(int argc, char** argv) {
int* x = (int *) malloc(4 * sizeof(int));
int i;
for(i = 0; i < 4; i++) {
x[i] = i;
printf("X[%d] = %d\n", i, x[i]);
}
x = (int *) realloc(x, 4 * sizeof(int));
for(i = 0; i < 8; i++) {
x[i] = i;
printf("X[%d] = %d\n", i, x[i]);
// free(x[i]);
}
free(x);
}
I get the following:
libC abort error: * glibc detected ./a.out: free(): invalid next size (fast): 0x00000000014f8010 **
i tried to free inside the last loop, but that still gives a problem. Where am I going wrong?

realloc() does not increase the allocated memory by the specified amount. It reallocates exactly the requested amount of bytes. So if you want to resize your array to be 8 integers long, you'll need to:
x = realloc(x, 8 * sizeof(int));
Btw, do not cast the returned value of malloc() and realloc() in C:
http://c-faq.com/malloc/mallocnocast.html

Related

Debug Error! HEAP CORRUPTION DETECTED in C

I tried to use dynamic allocation and I didnt sucsses to write it without warnings. I get debbug error with the 'free' function:
This is my program:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define size 1
int* symetri(int set1[size], int set2[size]);
int main() {
int* difference;
int set1[size], set2[size];
for (int i = 0; i < size; i++)
scanf("%d", &set1[i]);
for (int i = 0; i < size; i++)
scanf("%d", &set2[i]);
difference = symetri(set1, set2);
free(difference);
return 0;
}
int* symetri(int set1[size], int set2[size])
{
int* new_arr = (int*)malloc(size * sizeof(int));
while (new_arr == NULL)
new_arr = (int*)malloc(size * sizeof(int));
int counter = 0;
bool sym;
for (int i = 0; i < size; i++) {
new_arr[counter] = set1[i];
counter++;
}
new_arr[counter] = -1;
return new_arr;
}
If free crashes with an error message about heap corruption in a program this simple, it's almost certainly because you wrote to memory that doesn't belong to you. And you did, with this line at the end of symetri:
new_arr[counter] = -1;
You need to make your allocation of new_arr another sizeof(int) longer if you want to write to the end after looping over it.

Why am I getting junk values despite using calloc()?

I would like to know why the first two elements are always non-zero. I don't know how more I can describe the question, but this is not allowing me to post the question, so I'm writing this. Not sure if this will work.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
void printMatrix(int **m)
{
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++)
printf("%d ", m[i][j]);
printf("\n");
}
}
int main(int argc, char const *argv[])
{
int **matrix;
matrix = (int **) calloc(sizeof(int), SIZE);
for (int i = 0; i < SIZE; ++i)
matrix[i] = (int *) calloc(sizeof(int), SIZE);
printf("%s\n", "Matrix initialized.");
printMatrix(matrix);
return 0;
}
Output:
Matrix initialized.
1371548192 32653 0
0 0 0
0 0 0
You're not allocating enough memory:
matrix = (int **) calloc(sizeof(int), SIZE);
Here you're attempting to create an array of 3 int *, but you're only allocating space for 3 int. If a pointer is larger than an int on your system, which it most likely is, you write past the end of the array when you create the arrays for each row. Writing past the end of allocated memory invokes undefined behavior.
Since you're creating an array of int *, use that for the size of each element:
matrix = calloc(sizeof(int *), SIZE);
Also, don't cast the return value of malloc/realloc/calloc, as that can mask a bug if you forget to #include <stdlib.h>
The code uses calloc(sizeof(int), SIZE), but the actual datatype in the structure is int *, leading to insufficient memory allocation on some systems (mine gives int size as 4 and int * size as 8).
Here's a rewrite suggestion (we'll swap size parameters in the calloc call per its header):
int main(int argc, char const *argv[]) {
int **matrix;
if (!(matrix = calloc(SIZE, sizeof(*matrix)))) {
fprintf(stderr, "calloc failed");
return 1;
}
for (int i = 0; i < SIZE; ++i) {
if (!(matrix[i] = calloc(SIZE, sizeof(*(matrix[i]))))) {
fprintf(stderr, "calloc failed");
return 1;
}
}
printf("%s\n", "Matrix initialized.");
printMatrix(matrix);
return 0;
}
Here, we use *matrix and *matrix[i] instead of hard coding the types int * and int respectively. This can help us avoid bugs and hunting for locations to change code if we need to make type adjustments at some point.
We also check that calloc succeeds by testing that the pointer is non-NULL. Failing to do so can introduce difficult-to-find bugs due to undefined behavior.
Note Do I cast the result of malloc?.
Reference manual describes calloc as:
void* calloc (size_t num, size_t size);
So, calloc takes firstly num of elements and then size of a particular element
Try:
matrix = (int **) calloc(SIZE, sizeof(int *));

Memory leak when rewriteing a 2d array

I want to call a function that uses my 2d dynamic array to create another 2d dynamic array and then rewrite the value for my first array. So the code is something like this:
#include <stdio.h>
#include <stdlib.h>
int **bigger(int **A)
{
int i;
int **A2 = (int **)malloc(10 * sizeof(int *));
for(i = 0; i < 10; i++)
A2[i] = (int *)malloc(10 * sizeof(int));
return A2;
}
int main(void)
{
int i;
int **A = (int **)malloc(5 * sizeof(int *));
for(i = 0; i < 5; i++)
A[i] = (int *)malloc(5 * sizeof(int));
A = bigger(A);
for(i = 0; i < 10; i++)
free(A[i]);
free(A);
return 0;
}
If I check it with valgrind --leak-check=yes I get total heap usage: 6 allocs, 3 frees, 240 bytes allocated. How can I solve this memory leak ?
TL:DR, you're not re-writing, you're overwriting.
The problem is in
A = bigger(A);
inside bigger() function, you're allocating new memories and then, storing the same back into A, which makes you lose the pointer to previously allocated memories, thus rendering them unreachable and are not free()-d. Those causes the leak here.
You need to use realloc() for resizing already malloc()ed memory regions.
Otherwise, before you call malloc() again, inside the bigger(), you ought to free() the available memories.

Error free(): Invalid next size (fast)

I have a very simple program that malloc()'s some data, initializes it, then frees it and I keep getting this error. I have no idea why this is happening, any ideas?
#include <stdlib.h>
#include <stdio.h>
int main(){
int * big_mem;
int row_size = 4096; //not sure about this....
int num_rows = 5;
int const_val = 0xFFFFFFFF;
big_mem = (int *) malloc(row_size * num_rows);
if(!big_mem){
printf("Failed to malloc, exiting...");
return 0;
}
i = 0;
for(; i < row_size * num_rows; ++i){
big_mem[i] = const_val;
}
printf("Initialized mem, ");
free(big_mem);
big_mem = NULL;
return 0;
}
Output:
*** Error in `./test': free(): invalid next size (fast): 0x0000000000819010 ***
Use malloc(row_size * num_rows * sizeof(int)) .
You didn't malloc enough memory so your loop wrote past your malloc()ed memory. I'm surprised you didn't just get a segmentation fault.
You should write:
big_mem = (int *) malloc(row_size * num_rows * sizeof(int));

C: Allocating memory confusion

For this code
#include <stdlib.h>
#include <stdio.h>
int *f (int n)
{
int *ptr = malloc (sizeof (int));
*ptr = n;
return ptr;
}
int main()
{
int i;
int **ptr = malloc (sizeof (int *));
ptr[0] = f (0);
for (i = 0; i < 5; ++i)
{
ptr = realloc (sizeof (int *) * (i + 2));
ptr[i + 1] = malloc (sizeof (int));
ptr[i + 1] = f (i + 1);
}
for (i = 0; i < 5; ++i)
{
printf ("%d\n", *ptr[i]);
free (ptr[i]);
}
free (ptr);
return 0;
}
does program allocate twice than it is needed?
Yes, You don't need the malloc in main as it is immediately overwritten on the next line and you leak that memory. Is this a homework question?
EDIT for question change
This is now leaking memory in an odd way.
The first few lines aren't leaking but when you get into the loop you're allocating and assigning randomly. (As a first, realloc takes as it's first arguement a pointer to reallocate, so you're missing ptr in there)
Now you're allocating ptr to be of size 2, then 3 then 4 etc... up to 6. And then immediately leaking that memory as you overwrite the pointer with the call to f()
You could write that all like this:
int i;
int **ptr = malloc (sizeof(int*) * 6);
for (i = 0; i < 6; ++i)
{
ptr[i] = f(i);
}
for (i = 0; i < 6; ++i)
{
printf ("%d\n", *ptr[i]);
free (ptr[i]);
}
free (ptr);
return 0;
As an aside, you should in general try not to allocate memory too often, it is relatively slow. If you can use the stack you should, and if not, try and allocate all the memory you need up front, calling realloc in a loop is a bad idea and should be avoided.
In this specific case you don't need a pointer to a pointer, you could have just allocated one array of 6 integers, with int* array = malloc(sizeof(int) * 6) and then array[0] = 0; which would be easier and better.
Yes, it does allocate twice the needed memory. Also, the value of "ptr" in main is overwrite by return of "f" so you don't even have a chance to free it. You could remove the call to malloc in "main":
int main()
{
int *ptr = f (3);
printf ("%d\n", *ptr);
free (ptr);
return 0;
}

Resources