Debug Error! HEAP CORRUPTION DETECTED in C - 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.

Related

Free Memory of 2d Array in struct

I'm writing a little game in C and I wanted to test it with Valgrind.
Here is a little code example:
#include <stdio.h>
#include <stdlib.h>
typedef struct Game {
int** field;
} Game;
void buildfield(Game* game, int length);
void printfield(Game* game, int length);
void freefield(Game* game, int length);
int main()
{
struct Game* game = NULL;
game = malloc(sizeof (struct Game));
buildfield(game, 10);
printfield(game, 10);
freefield(game, 10);
free(game);
return 0;
}
void buildfield(Game* game, int length)
{
game->field = (int**)malloc((sizeof (int*)) * 20);
int i;
for (i = 0; i < 20; i++) {
game->field[i] = (int*) malloc((sizeof (int)) * length);
}
for (int line = 0; line < length; line++) {
for (int col = 0; col < 81; col++) {
game->field[col][line] = 0;
}
}
}
void printfield(Game* game, int length)
{
for (int i = 0; i < length; i++) {
printf("\n");
for (int j = 0; j < 20; j++) {
printf("%d",game->field[i][j]);
}
}
}
void freefield(Game* game, int length)
{
for (int i = 0; i < length; ++i) {
free(game->field[i]);
}
free(game->field);
}
Valgrind is saying:
HEAP SUMMARY:
==6239== in use at exit: 968 bytes in 22 blocks
==6239== total heap usage: 22 allocs, 0 frees, 968 bytes allocated
Why don't I free the allocations?
"Why don't I free the allocations?"
As noted in comments, there is extra complication in the code caused by use of unexplained values ( magic numbers ) to both create and free memory. For reasons explained in the link, among other problems, this can make matching count of frees with count of allocations difficult. The mis-match in times each of these is called in the reason Valgrind indicated blocks of memory remaining at the end of execution.
The following is your code with suggestions, including those specific to clearly applying the same number of calls to free() as to [m][c]alloc() (I chose to use calloc() here to avoid another loop (or memset()) to initialize memory.)
Note also, you may need to change the values that this example uses for #defines to meet your needs, but you only need to change them in one place, (at top of file.)
typedef struct Game {
int** field;
} Game;
void buildfield(Game *game, int length);
void printfield(Game *game, int length);
void freefield(Game *game, int length);
#define COUNT 20//replace all magic numbers
#define LENGTH 10//(change values of #defines to change shape and size of memory)
int main(void)//use a complete prototype for main
{
struct Game* game = NULL;//pointer needs memory
game = malloc(sizeof (struct Game));
buildfield(game, LENGTH);
printfield(game, LENGTH);
freefield(game, LENGTH);
free(game);
return 0;
}
void buildfield(Game *game, int length)
{ //Note - not optimal to cast return of [c][m]alloc in C (only in C++)
game->field = calloc(COUNT, sizeof(game->field));
int i;
for (i = 0; i < COUNT; i++) {
game->field[i] = calloc(LENGTH, (sizeof (game->field[i])) );
}
}
void printfield(Game *game,int length)
{
for (int i = 0; i < COUNT; i++) {
printf("\n");
for (int j = 0; j < LENGTH; j++) {
printf("%d",game->field[i][j]);
}
}
}
void freefield(Game *game,int length)
{
for (int i = 0; i < COUNT; ++i) {
free(game->field[i]);
}
free(game->field);
}
Well in the function buildfield()
You have alloted 20 blocks of memory
game->field = (int **) malloc(sizeof(int *) * 20);
Hence the most you can access by [] operator is game->field[19]
But in the loop the program tries to access more blocks ahead of game->field[19]
Causing a segmentation fault
And the program crashes then and there. Without ever returning to main() let alone reach the free() statement. So it means your program never completed in the first place and crashed midway.
for (int line = 0; line < length; line++)
{
for (int col = 0; col < 81; col++) //when col becomes 20
{
game->field[col][line] = 0; //this statement will try to access the non-alloted memory block when col is 20
}
}
To check if your program crashes midway add some print statements at the end of the statements related to accessing memory or use a debugger. Because that's the most common source of runtime errors.
Also for this code try to keep in mind the maximum no. of memory blocks alloted that can be accessed by a specific pointer and change the condition of the marked for loop so that it will access memory within the allocation limit that is the no. of blocks you alloted using the malloc function.
The problem here is not the free() not working. But the segmentation fault.
Assuming the code you provided is the exact replica of your code

C, Segmentation fault while using dynamic array in struct

I'm trying to add new element to dynamic array in C (I know that I must free all memory. I will do it later), but I get this error every time:
But, what is strange, if I compile from terminal, like that, code works properly.
So, where is the error and how i can beat it?
Thank you!
All my code:
main.c
#include <stdio.h>
#include <stdlib.h>
typedef struct vector
{
int size;
int *array;
int alreadyIn;
}vector;
vector *vectorInit(int size)
{
vector *newVec = (vector *)malloc(sizeof(vector));
if(!newVec){printf("No memory!\n"); return NULL;}
newVec->size = size;
newVec->array = (int *)malloc(size * sizeof(int));
return newVec;
}
void allocNewMemory(vector *vect, int howMuch)
{
vect->array = (int *)realloc(vect->array ,(vect->size + howMuch) * sizeof(int));
vect->size += howMuch;
}
void pushBack(vector *vect, int number)
{
int howMuch = 5;
if(vect && vect->alreadyIn < vect->size)
{
vect->array[vect->alreadyIn] = number;
vect->alreadyIn++;
}
else
{
printf("Alloc new memory for %d elements...\n", howMuch);
allocNewMemory(vect, howMuch);
pushBack(vect, number);
}
}
void printVector(vector *vect)
{
for (int i = 0; i < vect->alreadyIn; i++)
{
printf("%d ", vect->array[i]);
}
printf("\n");
}
int main()
{
int startSize = 4;
vector * vec = vectorInit(startSize);
for (int i = 0; i < 6; i++)
{
pushBack(vec, i+1);
}
printVector(vec);
return 0;
}
You never initialize the alreadyIn member in the structure. That means its value will be indeterminate (and seemingly garbage or random).
You need to explicitly initialize it to zero:
vector *vectorInit(int size)
{
vector *newVec = malloc(sizeof(vector));
if(!newVec)
{
printf("No memory!\n");
return NULL;
}
newVec->size = size;
newVec->array = malloc(size * sizeof(int));
newVec->alreadyIn = 0; // Remember to set this to zero
return newVec;
}
This problem should have been easy to detect in the debugger.
Also note that I removed the casts from malloc. One should not cast the result of malloc, or really any function returning void *.

Why do I get a segmentation fault by declaring a 2d array in c?

I am new to threads and I have a program that uses threads to find the minimum number out of a 2d array and later on, it finds the distance that the other elements of the array have from the minimum number and stores them in another array.
The user should enter the size of the array and the number of threads he wants to use.
I tried the program below for 1d array and it worked just fine. When I converted it to work for a 2d array it started crashing and throwing a segmentation fault. I, however, cannot find which part of the 2d declaration is wrong.
Any help is really appreciated.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <pthread.h>
struct Parameters
{
// input
int s,p; //n is size of array, p is number of threads
int** array; //array with elements
int start;
int end;
// output
int smallest;
int pos; //position if minimum
int** B; //array that holds the distances
};
void* min(void* args)
{
struct Parameters* p = (struct Parameters*)args;
int **array = p->array;
int **B1 = p->B;
int start = p->start;
int end = p->end;
int smallest = array[start][start];
int pos = p->pos;
int distance;
//find the smallest
for (int i = start; i < end; i++)
{
for(int j = start; j < end; j++)
{
if (array[i][j] < smallest)
{
smallest = array[i][j];
pos = i;
}
}
}
//find the distances
for(int i = 0; i < ((struct Parameters*)args) -> s; i++)
{
for(int j = 0; j < ((struct Parameters*)args) -> s; j++)
{
distance = abs(pos - i);
B1[i][j] = distance;
}
}
params->smallest = smallest;
params->B = B1;
return NULL;
}
int main()
{
int smallest,pos;
int s,p;
struct Parameters *ptr = (struct Parameters *)malloc(sizeof(struct Parameters));
if(ptr == NULL)
{
printf("Not enough. Try again \n");
exit(0);
}
printf("Type s\n");
scanf("%d",&(ptr->s));
printf("Type p\n");
scanf("%d", &(ptr->p));
// declare an array of threads and associated parameter instances
pthread_t threads[(ptr->p)];
struct Parameters thread_parameters[(ptr->p)] ;
int arr[ptr->s][ptr->s];
int B2[ptr->s][ptr->s];
// intialize the array
for(int i=0; i< ptr->s; i++)
{
for(int j=0; j< ptr->s; j++)
{
printf("Type a \n");
scanf("%d",&arr[i][j]);
}
}
// smallest needs to be set to something
smallest = arr[0][0];
// start all the threads
for (int i = 0; i < ptr->p; i++)
{
memcpy(arr, thread_parameters[i].array, sizeof(arr));
thread_parameters[i].s = ptr->s;
memcpy(Bb, thread_parameters[i].B, sizeof(B2));
thread_parameters[i].start = i * (ptr->s / ptr->p);
thread_parameters[i].end = (i+1) * (ptr->s / ptr->p);
pthread_create(&threads[i], NULL, min, &thread_parameters[i]);
}
// wait for all the threads to complete
for (int i = 0; i < ptr->p; i++)
{
pthread_join(threads[i], NULL);
}
// Now aggregate the "smallest" and "largest" results from all thread runs
for (int i = 0; i < ptr->p; i++)
{
if (thread_parameters[i].smallest < smallest)
{
smallest = thread_parameters[i].smallest;
}
}
printf("Smallest is %d\n", smallest);
thread_parameters[ptr->p].B[ptr->s][ptr->s];
for (int i = 0; i < 1; i++)
{
for(int j = 0; j < ptr->s;j++)
{
for(int k = 0; k < ptr->s; k++)
{
printf("Element %d is %d away from min\n",j,thread_parameters[i].B[j][k]);
}
}
}
return 0;
}
Thank you!!
The issue with your code might also come from :
memcpy(arr, thread_parameters[i].array, sizeof(arr));
...
memcpy(Bb, thread_parameters[i].B, sizeof(B2));
as thread_parameters[i].array and thread_parameters[i].B are not allocated, if you are only reading the array it might b fine to only pass them by address
thread_parameters[i].array = arr
but for thread_parameters[i].B you would need to allocate the arrays and perform a deep copy (memcpy would not work)
The below text does not answer the question but does provide some insight on VLA usage
One reason for causing the segmentation with a declaration of a Variable Length Array is that the value is to large to allocate the array on the stack (some compiler choose this option, this choice might have performance reason).
The is not much option to recover cleanly from failure to allocate memory on the stack as there is little way to clean up stack memory during runtime within the same stack context.
You can mitigate the issue by allocating your 2D arrays on the heap instead, some of the strategies are available here(thanks #Lundin) and here.
int** alloc_2d_int_array(size_t rows, size_t cols) {
int **result = malloc(rows * sizeof(int *));
if(result == NULL) {
// could not allocate more memory
return NULL;
}
size_t row_size = cols * sizeof(int);
for(int i=0; i < rows; ++i) {
result[i] = malloc(row_size);
if(result[i] == NULL) {
// could not allocate more memory
// cleanup
return NULL;
}
}
return result;
}
the above implementation have not been tested, but does compile, there are still risk of integer overflow.
Then use the above define function as following:
int **arr = alloc_2d_int_array(ptr->s, ptr->s);
int **B2 = alloc_2d_int_array(ptr->s, ptr->s);
easier implementation (see here(thanks #Lundin))
int **arr = malloc(sizeof(int[ptr->s][ptr->s]);
int **B2 = malloc(sizeof(int[ptr->s][ptr->s]);

Assigning a return value of a function in heap

I am having trouble with assigning a return value of a function in heap part of the program. When I tried it in main, it gives an error "Segmentation fault". I believe it is because of the size of my array, which is the return value that I mentioned earlier because when I make my max_size smaller, the code works correctly (I think up to 45000). When I call the function in main, it uses the memory of stack, which is much smaller than memory of heap. Therefore I tried to call the function in heap and make the assignment in there but the compiler gave an error
deneme.c:6:15: error: initializer element is not constant
int *primes = listPrimes(1000000, &size);
After that I did some research and found out that stack is 8 MB memory, which is around 8000000 bytes. Then I estimated my array size as using the prime number theorem (up to 1000000, there are approximately 200000 primes) and sizeof(int) = 4 bit value so it gives 100000 bytes, which is much less than 8 MB. Therefore I have two questions in mind:
1. Why the compiler gives segmentation fault error although my array size is not too large?
2. How can I make the assigment in heap instead of main in order to avoid this problem?
Here is my code:
#include "mathlib.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int *listPrimes(int max_size, int *size) {
*size = 1;
int *result = malloc(*size * sizeof(int));
int i;
int index = 1;
// Finding the list of primes using a sieve algorithm:
int *nums = malloc(max_size*sizeof(int));
for (i = 0; i < max_size; i++) {
nums[i] = i;
}
result[0] = 2;
int j = 2;
while (j < max_size) {
int k = j;
while (j*k <= max_size) {
nums[j*k] = 0;
k++;
}
if (j == 2) {
j++;
*size = *size + 1;
result = realloc(result, *size * sizeof(int));
result[index++] = nums[j];
}
else {
j += 2;
if (nums[j] != 0) {
*size = *size + 1;
result = realloc(result, *size * sizeof(int));
result[index++] = nums[j];
}
}
}
return result;
}
and main function:
#include <stdio.h>
#include <stdlib.h>
#include "mathlib.h"
int size = 0;
int *primes = listPrimes(1000000, &size);
int main() {
printf("size = %d\n", size);
for (int i = 0; i < size; i++) {
printf("%d th prime is %d\n", i+1, primes[i]);
}
free(primes);
return 0;
}
Use unsigned int for j, k and max_size in listPrimes and it works properly . Below is the tested code:
// #include "mathlib.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int size = 0;
int *
listPrimes (unsigned int max_size, int *size)
{
*size = 1;
int *result = malloc (*size * sizeof (int));
int i;
int index = 1;
// Finding the list of primes using a sieve algorithm:
int *nums = malloc (max_size * sizeof (int));
for (i = 0; i < max_size; i++)
{
nums[i] = i;
}
result[0] = 2;
unsigned int j = 2;
while (j < max_size)
{
unsigned int k = j;
while (j * k <max_size)
{
nums[j * k] = 0;
k++;
}
if (j == 2)
{
j++;
*size = *size + 1;
result = realloc (result, *size * sizeof (int));
result[index++] = nums[j];
}
else
{
j += 2;
if (nums[j] != 0)
{
*size = *size + 1;
result = realloc (result, *size * sizeof (int));
result[index++] = nums[j];
}
}
}
free(nums);
return result;
}
int
main ()
{
int *primes = listPrimes (1000000, &size);
printf ("size = %d\n", size);
for (int i = 0; i < size; i++)
{
printf ("%d th prime is %d\n", i + 1, primes[i]);
}
free (primes);
return 0;
}
nums is allocated to have max_size elements, so the index of its last element is max-size-1.
This loop:
while (j*k <= max_size) {
nums[j*k] = 0;
k++;
}
may access an element with index j*k that equals max_size, thus writing beyond the end of the array. The loop should be limited to j*k < max_size.
Regarding your second question, the size of the result array is determined while finding the primes and is not readily calculable in advance, so it cannot easily be allocated prior to calling listPrimes. It could be done by evaluating the prime-counting function, but that is likely more than you want to do for this project.

Error with the malloc command in C

my Excercice is to initalise space from the heap in function1(); and to create an array there. In the main I have to print the array. What have I done wrong?
CODE
#include <stdio.h>
#include <stdlib.h>
int functionOne(int size);
int main()
{
int size = 0,i;
scanf("%d",&size);
int *arrsize = functionOne(size);
printf("rueckgabe %d",arrsize);
int arr [*arrsize];
arr[0] = 7;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;
arr[4] = 5;
for(i=0; i<size; i++)
{
printf("[%d]",arr[i]);
}
}
int functionOne(int size)
{
int *arr;
arr = NULL;
arr = malloc(size * sizeof(int));
return arr;
}
The thing is on the line printf("rueckgabe %d",arrsize); you are printing the address returned by other function - that too using wrong format specifier.
Suppose you allocated memory for 4 int using the other function functionOne and the memory of the allocated chunk is being returned - now when you do *arrsize you are basically accessing the 0th positional int value. But as it is uninitialized - the value of it is indeterminate.
Earlier you were declaring VLA with uninitialized value. This is undefined behavior. Also there is no meaning printing the contents of the variable length array unless you initialize them (i.e.,printf("[%d]",arr[i]);).
Return value of the function functionOne is int but you are returning int*.
There are many other things you can follow in the code, like correcting the indentation - checking the return value of malloc and changing the signature of main from int main() to int main(void).
I have added some demo code showing whatever I have mentioned above:
Edit:
#include <stdio.h>
#include <stdlib.h>
int* functionOne(int size);
int main(void)
{
int size = 0;
if( scanf("%d",&size)!= 1){
fprintf(stderr,"Error in input\n");
exit(EXIT_FAILURE);
}
if( size <= 0){
fprintf(stderr,"Error in input [size]\n");
exit(EXIT_FAILURE);
}
int *arr = functionOne(size);
for(size_t i = 0; i < size; i++){
arr[i]=i;
}
for(size_t i = 0; i<size; i++){
printf("arr[%zu] = %d \n",i,arr[i]);
}
free(arr);
return 0;
}
int* functionOne(int size)
{
int *arr;
arr = malloc(sizeof(int)*size);
if( arr == NULL && size > 0){
perror("malloc");
exit(EXIT_FAILURE);
}
return arr;
}

Resources