How to properly free() my mallocs in c - c

I need to have a dynamic array so I have used malloc in my code...However I don't know how to successfully free the memory afterwards. Somewhere in my code I believe I have a pointer re-assignment which leads to dangling pointer error (when i do child2=child1). Does anyone know how to free my mallocs properly? Thanks in advance.
My actual code is below:
typedef struct Edge//per solution
{
int label;//label
float weight;//energy of each edge
} edge;
// creating the chrom structure
typedef struct Chrom
{
edge **gene;
float fitness_score;
}
In one of my functions i have the following, where pop_size and num_nodes was previously calculated as 100 and 10 respectively.
Chrom* child1;
Chrom* child2;
//allocate memory of child
child1 = malloc(num_nodes * sizeof(child1));
child2 = malloc(num_nodes * sizeof(child2));
if(child1 == NULL||child2 == NULL)
printf("ERROR1: Memory allocation failed!");
for(x = 1; x <= num_nodes; x++)
{
child1[x].gene = malloc(num_nodes * sizeof(edge*));
child2[x].gene = malloc(num_nodes * sizeof(edge*));
if(child1[x].gene == NULL||child2[x].gene == NULL)
printf("ERROR2: Memory allocation failed!");
for(y = 0; y < num_nodes; y++)
{
child1[x].gene[y] = malloc(num_nodes * sizeof(edge));
child2[x].gene[y] = malloc(num_nodes * sizeof(edge));
if(child1[x].gene[y] == NULL||child2[x].gene[y] == NULL)
printf("ERROR3: Memory allocation failed!");
}
}
//do something...
for(i=0; i<pop_size; i++)
for(x=0; x<num_nodes; x++)
for(y=0;y<num_nodes;y++)
child2[i].gene[x][y].label=child1[i].gene[x][y].label;
free(child1);//can i free the memory like this?
free (child2);// will it automatically do all 'arrays'?
Also, must I first check if memory was allocated properly before freeing it?

child1 = malloc(num_nodes * sizeof(child1));
this is incorrect. You are allocating space for num_nodes pointers (child1 is a pointer to Chrom). You want to allocate space for num_nodes Chrom instances.
Change it to
child1 = malloc(num_nodes * sizeof(*child1));

First of all, you allocate space for Chrom pointers, not the space for Chrom structures so I am surprised that child1[x].gene works without crashing but to only answer the questions posed as comments in your code,
free(child1);//can i free the memory like this?
free (child2);// will it automatically do all 'arrays'?
child1 is an array of pointers and each of those pointers points to allocated memory which will be lost when you free(child1). I would free each pointer child1[x].gene first and then free child1. Same thing for child2.
This is probably close to what you want:
typedef struct Edge//per solution
{
int label;//label
float weight;//energy of each edge
} edge;
// creating the chrom structure
typedef struct Chrom
{
edge *gene; // changed from edge**
float fitness_score;
};
int main(void)
{
int num_nodes = 3;
int x;
struct Chrom* child1;
// if you want num_nodes Chrom entries
child1 = malloc(num_nodes * sizeof(struct Chrom));
// Allocating individual edges (I don't know why you declare edge** gene
// so I will assume that what you intended was edge* gene
for(x = 1; x <= num_nodes; x++)
{
child1[x].gene = (edge*)malloc(sizeof(struct Edge));
}
// deallocate your memory
for(x = 1; x <= num_nodes; x++)
{
free(child1[x].gene);
}
// free your array of Chroms
free(child1);
return 0;
}
Here is what the code could be if you want a 2D array of edegs within each Chrom; Also, there is a bug in my previous answer; x should be initialized to zero in the for loop rather than to 1 because this will cause an array index out of bounds and use lower-than instead of lower-than-or-equal. (WARNING: I only tested it slightly):
typedef struct Edge//per solution
{
int label;//label
float weight;//energy of each edge
} edge;
// creating the chrom structure
typedef struct Chrom
{
edge **gene;
float fitness_score;
};
int main(void)
{
int num_nodes = 3;
int num_edges_x = 2;
int num_edges_y = 3;
int x, j;
struct Chrom* child1;
// if you want num_nodes Chrom entries
child1 = malloc(num_nodes * sizeof(struct Chrom));
// Allocating 2D array of edges for each Chrom
// USE zero-based indexing.
for(x=0; x < num_nodes; x++)
{
child1[x].gene = (edge**)malloc(num_edges_x * sizeof(edge*));
// initialise you array of edges
for (j=0; j<num_edges_x; j++)
{
child1[x].gene[j] = (edge*)malloc(num_edges_y * sizeof(edge));
}
}
// Use a child1[x].gene[x][y]
child1[0].gene[0][0].label = 3;
child1[0].gene[0][0].weight = 7.2F;
printf("\nlabel: %d - weight: %f", child1[0].gene[0][0].label, child1[0].gene[0][0].weight);
child1[1].gene[0][0].label = 1;
child1[1].gene[0][0].weight = 12.4F;
printf("\nlabel: %d - weight: %f", child1[1].gene[0][0].label, child1[1].gene[0][0].weight);
child1[1].gene[1][0].label = 5;
child1[1].gene[1][0].weight = 112.6F;
printf("\nlabel: %d - weight: %f", child1[1].gene[1][0].label, child1[1].gene[1][0].weight);
// deallocate your memory
for(x =0; x < num_nodes; x++)
{
for (j=0; j<num_edges_x; j++)
{
free(child1[x].gene[j]);
}
free(child1[x].gene);
}
free(child1);
return 0;
}

Related

initializing array pointer to a struct

I get the Error run-time check failure #3, and i have to initialize P and i know why but not how to do it.
Points is supposed to be a variable 2D array like float* points[3] for testing purposes its constant for now.
CVAPI(CvPOSITObject*) lvCreatePOSITObject( float points[5][3], int point_count )
{
CvPoint3D32f* P; //array of structs with int x,y,z
for(int i = 0; i< point_count; i++)
{
P[i].x = points[i][0];
P[i].y = points[i][1];
P[i].z = points[i][2];
}
return cvCreatePOSITObject(P,point_count);
}
I don't know much about OpenCV, but I think you should allocate some memory to store the data.
#include <stdlib.h> // add this to the head of the file to use malloc
CVAPI(CvPOSITObject*) lvCreatePOSITObject( float points[5][3], int point_count )
{
CvPoint3D32f* P; //array of structs with int x,y,z
P = malloc(sizeof(CvPoint3D32f) * point_count); // allocate some memory
for(int i = 0; i< point_count; i++)
{
P[i].x = points[i][0];
P[i].y = points[i][1];
P[i].z = points[i][2];
}
return cvCreatePOSITObject(P,point_count);
}
This code may be bad because this may not free the allocated buffer.

How to allocate and declare a 3D of array of structs in C?

How do you allocate and declare a 3D array of structs in C?
Do you first allocate the array or declare it?
I feel like you have to allocate it first so you can declare it so it is on the heap, but then how do you allocate something that hasn't been made yet?
Also, should you allocate it all at once or element by element?
Also am i putting the structs into the array correctly?
My guess on how to do it would be:
header.h
struct myStruct{
int a;
int b;
};
typedef struct myStruct myStruct_t;
main.c
#include "header.h"
#include <stdio.h>
#include <stdlib.h>
int main(void){
int length=2;
int height=3;
int width =4;
myStruct_t *elements;
struct myStruct arr = (*myStruct_t) calloc(length*height*width, sizeof(myStruct);
//zero based array
arr[length-1][height-1][width-1];
int x=0;
while(x<length){
int y=0;
while(y<height){
int z=0;
while(z<depth){
arr[x][y][z].a=rand();
arr[x][y][z].b=rand();
z++;
}
y++;
}
x++;
}
return 0;
}
The easy way is:
myStruct_t (*arr2)[height][width] = calloc( length * sizeof *arr );
Then your loop can access arr2[x][y][z].a = rand(); and so on. If you're not familiar with this way of calling calloc, see here. As usual with malloc, check arr2 against NULL before proceeding.
The triple-pointer approach is not really a practical solution. If your compiler does not support variably-modified types then the array should be flattened to 1-D.
There are a couple of different ways to do this, depending on what you want. First, you can allocate your array on the stack (in C99 and some compilers) like this:
myStruct_t arr[length][height][depth];
If you want it allocated on the heap, then you can do a single allocation of the appropriate size. You can then either do the index calculation yourself or make a pointer do the work for you (in C99 and some compilers):
void *buf = malloc(length * height * width * sizeof(myStruct_t));
myStruct_t *arr = buf;
myStruct_t (*arr2)[height][width] = buf;
/* TODO: check return of malloc */
...
arr[x * height * width + y * width + z].a = rand(); /* indexing the C89 way */
arr2[x][y][z].b = rand(); /* indexing the C99 way */
Or you can manually allocate the multiple dimensions.
#include <stddef.h>
#include <stdlib.h>
typedef struct myStruct
{
int a, b;
} myStruct_t;
int main()
{
myStruct_t ***arr;
int length = 5000, height = 1000, depth = 20;
int x, y, z;
int ret = 1;
if (NULL == (arr = malloc(length * sizeof(myStruct_t**))))
goto FAIL;
for (x = 0; x < length; ++x)
{
if (NULL == (arr[x] = malloc(height * sizeof(myStruct_t*))))
goto FAIL_X;
for (y = 0; y < height; ++y)
{
if (NULL == (arr[x][y] = malloc(depth * sizeof(myStruct_t))))
goto FAIL_Y;
for (z = 0; z < depth; ++z)
{
arr[x][y][z].a = rand();
arr[x][y][z].b = rand();
}
}
}
/* TODO: rest of program logic */
/* program successfully completed */
ret = 0;
/* reclaim arr */
FAIL_CLEANUP: /* label used by TODO code that fails */
for (x = length - 1; x >= 0; --x)
{
for (y = height - 1; y >= 0; --y)
{
free(arr[x][y]);
FAIL_Y:
;
}
free(arr[x]);
FAIL_X:
;
}
free(arr);
FAIL:
return ret;
}
This last version uses a lot more memory for all the explicit pointers it contains, its memory locality is worse and it's significantly more complex to properly allocate and reclaim. However, it does allow different sizes along your dimensions. For example, the array arr[0][4] can have a different size than arr[0][7] if you ever need that.
If you want to allocate it on the heap, then you probably want the second version with a single allocation and multi-dimension pointer (if available) or do the indexing yourself manually using appropriate math.

Iterate through a List and print items

I have a list like this
#include <stdio.h>
#include <stdlib.h>
struct ListItem
{
int x;
int y;
struct ListItem *next;
};
int main()
{
int x1 =0;
int y1 = 0;
printf("Please enter the x coordinate: ");
scanf("%d", &x1);
printf("Please enter the y coordinate: ");
scanf("%d", &y1);
struct ListItem root;
if( root.next == NULL )
{
root.x = x1;
root.y = y1;
//I dont know what should I assign here but I want to have about 30 locations
//root.next = struct ListItem next;
}
//WHAT SHOULD I DO HERE?
{
printf("Your location is : (%d,%d)\n", root.x, root.y);
}
}
Now I want to write a loop to iterate through it so that I can print every element on the list :)
Basically what I am trying to do is, I want to get the locations from the user and then I will print them.
Please help .
Linked list. Input coordinates until you enter zero.
#include <stdio.h>
#include <stdlib.h>
struct ListItem
{
int x;
int y;
struct ListItem *next;
};
int main()
{
int x1 =0;
int y1 = 0;
int iCount = 0; // keep count of the structures allocated
int iEach = 0;
struct ListItem root = { 0, 0, NULL};// declare and initialize the first structure
struct ListItem* pFreeListItem = NULL;// declare a pointer and initialize it null. use for freeing memory later
struct ListItem* pListItem = &root;// declare a pointer and initialize it to point to the first structure
while ( 1) { // the main loop
printf("Please enter the x coordinate: ");
scanf(" %d", &x1);
printf("Please enter the y coordinate: ");
scanf(" %d", &y1);
pListItem->x = x1; // use the pointer to assign the coordinate
pListItem->y = y1;
iCount++; // keep track of the number of structures
printf("Input complete for location number %d\n", iCount);
printf("Enter 0 to exit or any other number to continue: ");
scanf(" %d", &y1);
if ( y1 == 0) { // exit the loop if zero is entered
break;
}
else { // if zero was not entered
pListItem->next = malloc ( sizeof ( struct ListItem));// allocate memory for the next structure
if ( pListItem->next == NULL) {
//allocation failed
exit (1);
}
pListItem = pListItem->next; // set the pointer to point to the new 'next' structure
pListItem->next = NULL; // set this to null as no memory has yet been allocated
}
}
pListItem = &root; // set the pointer to the original structure root
for ( iEach = 0; iEach < iCount; iEach++) // loop through each structure. icount holds the number of structures
{
printf("Location number %d is : (%d,%d)\n", iEach + 1, pListItem->x, pListItem->y);
pListItem = pListItem->next; // set the pointer to the next structure
}
pListItem = root.next; // set the pointer to the first allocated structure
for ( iEach = 1; iEach < iCount; iEach++) // loop through each structure
//start with 1 as the first structure was not allocate and does not need to be freed. icount holds the number of structures
{
pFreeListItem = pListItem->next; // set the free pointer to the next structure
free ( pListItem); // free the memory for the structure
pListItem = pFreeListItem; // point to the free pointer
}
}
EDIT: this code will show the address of the pointers and maybe that will help clarify what is going on
else { // if zero was not entered
pListItem->next = malloc ( sizeof ( struct ListItem));// allocate memory for the next structure
if ( pListItem->next == NULL) {
//allocation failed
exit (1);
}
printf ( "pListItem points to %p and pListItem->next points to %p\n", pListItem, pListItem->next);
pListItem = pListItem->next; // set the pointer to point to the new 'next' structure
pListItem->next = NULL; // set this to null as no memory has yet been allocated
printf ( "NOW pListItem points to %p and pListItem->next points to %p\n", pListItem, pListItem->next);
}
Here's a toy program that works, demonstrating a list stored in an array.
Actually compiles with no warnings - gcc -Wall -Werror -std=c99 l.c
The dynamically allocated version using calloc, works to, if you want dynamic memory, so you can add to the list later.
ladm#ash:~/src/scratch> ./a.out|head | sed 's/^/ /'
array[ 0] : (1,1)
array[ 1] : (2,2)
array[ 2] : (3,3)
Your location is : (3,3)
Your location is : (2,2)
Your location is : (1,1)
array[ 2] : (3,3)
array[ 1] : (2,2)
array[ 0] : (1,1)
ladm#ash:~/src/scratch> cat l.c | sed 's/^/ /'
#include <stdio.h>
#include <assert.h>
typedef struct ListItem
{
int x;
int y;
struct ListItem *next;
} ListItem;
void getCoord(int *x, int *y) {
static int num = 1;
*x = *y = num++;
}
int main( int argc, char **argv) {
const int N = 3;
ListItem listN[ N];
/* ListItem *listN = calloc( N, sizeof( ListItem)); */ /* Dynamic allocation method */
/* First Coordinate */
listN[ 0].next = NULL; /* Add item at front of list */
getCoord( &listN[ 0].x, &listN[ 0].y); /* Does the scanf stuff */
/* Add new coords to the list */
for (int i=1; i < N; i++) {
getCoord( &listN[ i].x, &listN[ i].y); /* Does the scanf stuff */
listN[ i].next = &listN[ i-1]; /* Add item at front of list */
}
/* List built */
{
ListItem *first = &listN[ N-1];
/* Dump all the coords in backing store */
for (int i = 0; i < N; i++) {
printf("array[ %d] : (%d,%d)\n", i, listN[ i].x, listN[ i].y);
}
/* Print list following pointers - should be reversed */
for (ListItem *l = first; l != NULL; l = l->next) {
printf("Your location is : (%d,%d)\n", l->x, l->y);
}
/* Dump all the coords in backing store reversed */
for (int i = N-1; i >= 0; --i) {
printf("array[ %d] : (%d,%d)\n", i, listN[ i].x, listN[ i].y);
}
}
}
If you know the number of locations you will have, you better use an array or matrix, like:
int x[30];
int y[30];
or
int location[60];
or
int location[2][30];
And use a for loop to iterate over the elements.
If you don't know the number of locations, then you wish to search for LinkedList (or ArrayList) implementation in C. There are plenty of material on Internet teaching how to use those data structures.
A good way to iterate through a list would be making functions like give_successor and is_after_last, then using it in a for loop, like that:
struct ListItem *l;
struct ListItem *head;
for (l = head; !(is_after_last(l)); l = give_successor(l)) {
do_stuff(l);
}
Implementation of is_after_last may vary depending on implementation of the list: you might want to check if l == NULL or if l points to artificial element at the end of the list.
Function give_successor looks like that:
struct ListItem *give_successor(l) {
if (l == NULL)
return NULL;
return l->next
}
However, I recommend using tables and libraries like those.

Variable array size in c

I'm trying to declare arrays with a variable size, given by user input.
So far I have something like this:
typedef struct _object{
int rowsAmount;
int columsAmount;
int* rows;
int* colums;
} object;
object* newObject(int ra, int ca){
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->rows = [ra];
o->colums = [ca];
return o;
}
int main(){
newObject(3,4);
}
I expected this wouldn't work, but I want something like this, and I don't know how to do it.
It looks like you're basically implementing a dynamic Matrix object here. You want something like:
typedef struct _object{
int rowsAmount;
int columsAmount;
int* matrix;
int** rows;
} object;
object* newObject(int ra, int ca){
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->matrix = malloc(ra * ca * sizeof(int));
o->rows = malloc(ra * sizeof(int*));
for (size_t i = 0; i != ra; ++i) o->rows[i] = o->matrix + (i * ca);
return o;
}
You should also create a destructor function destroyObject, which similarly frees all the memory allocated for o and o->matrix.
Edit:
However, your comment that:
"I'm just trying to learn c, this is only about the setting the size.
I just happened to try it with 2 arrays"
...makes this question somewhat confusing, because it indicates you are not, in fact, trying to create a matrix (2D array) despite your use of "row"/"column" terminology here, but that you simply want to understand how to dynamically allocate arrays in C.
If that's the case, an array in C is dynamically allocated using a pointer variable and malloc:
size_t array_size = 10; /* can be provided by user input */
int* array = malloc(sizeof(int) * array_size);
And then later, the dynamically-allocated array must be freed once you are finished working with it:
free(array);
To dynamically allocate a 2d array of data in C:
Allocate the memory for the entire data. That memory is pointed to by arrayData.
Allocate an 1D Array of pointers one for each row
Point those pointers to the memory address corresponding each row
Code:
int *arrayData = malloc(sizeof(int) * rows * columns);
int **array = malloc(sizeof(int*) * rows);
for(int i=0; i < rows;++i){
array[i] = arrayData + i * columns;
}
You can now access the memory as array[row][col].
You can create a array with size input from user with out a structure.
int *array1;
int size;
// get input from user
array1 = malloc(sizeof(int)*size);
// do your stuff
free(array1);
if you want a 2D array,
int **array2;
int row, col;
int i;
array2 = malloc(sizeof(int*)*row);
for(i=0;i<row;++i)
array2[i] = malloc(sizeof(int)*col);
//use the array
for(i=0;i<row;++i)
free(array2[i]);
free(array2);
if you really need a structure array, then allocate memory for it in your newObject() function
typedef struct _object{
int rowsAmount;
int columsAmount;
int** array;
//int* colums;
} object;
object* newObject(int ra, int ca){
int i;
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->array = malloc(sizeof(int*)*ra);
for(i=0;i<ra;i++)
o-<array[i]=malloc(sizeof(int)*ca);
return o;
}
int main(){
newObject(3,4);
}
I think that quite often people use dynamic memory allocation when scoped variables can be used instead. For example, array sized from user's input can be allocated on stack without using malloc/free:
int array_size;
scanf("%d", &array_size);
if (array_size > 0) {
/* Allocate array on stack */
float array[array_size];
/* ... do smth with array ... */
}
/* Out of scope, no need to free array */
Of course if your data block is huge, heap memory is a must, but for small allocations scopes are just fine.
Easiest way is to use boost::multi_array
Not only will you get any number of dimensions, it's also stored very efficiently as a single contiguous block of memory rather than n dimensional array.
CPU's are designed to traverse arrays quickly, and you could potentially utilise caching/prefetch/pipelining features of the compiler using this.
Eg
// 2 dimensions
int xDim;
int yDim;
cin >> xDim; // From user..
cin >> yDim;
// Initialise array
boost::multi_array<int,2> my2dgrid(boost::extents[xDim][yDim]);
// Iterate through rows/colums
for(int j = 0 ; j < yDim-1; j++) { // Row traversal
for(int i = 0 ; i < xDim-1; i++) { // Column traversal
int value = grid[j][i]; // Get a value
grid[j][i] = 123; // set a value
// Do something...
}
#include <stdio.h>
#include <stdlib.h>
typedef struct _object{
int rowsAmount;
int columsAmount;
int **rows;
// int* colums;
} object;
object* newObject(int ra, int ca){
int r;
object* o = malloc(sizeof(object));
o->rowsAmount = ra;
o->columsAmount = ca;
o->rows = (int **)malloc(ra*sizeof(int *));
for(r=0;r<ra;++r)
o->rows[r] = (int*)malloc(ca*sizeof(int));
return o;
}
int main(){
object *obj= newObject(3,4);
obj->rows[2][3]=5;
return 0;
}

C Programming weird struct setup

I am trying to build this project and for some reason the program hangs when I run it.
It works fine if i comment out the data cache lines. but it cannot make a call to makeCache for two different caches i dont know why any C experts know. Im new to c.
/*
* main.c
*
* Created on: Sep 16, 2010
* Author: TJ
*/
#include <stdlib.h>
#include <stdio.h>
typedef struct {
int tag;
int valid;
int LRU;
int offset;
}directoryBlock;
typedef struct{
int setNumber;
directoryBlock blocks[];
}cacheSet;
typedef struct{
int cacheNumber;
cacheSet *sets[];
}cache;
cache* makeCache(cache *makeMe,int numberOfSets, int blocksPerSet);
int main(void)
{
int i = 0;
//cache * temp = makeCache(10,200);
i = 0;
int j = 0;
cache *instructions = malloc(sizeof(cache) + sizeof(cacheSet*));
cache *data = malloc(sizeof(cache) + sizeof(cacheSet*));
makeCache(instructions,20,300);
makeCache(data,20,300);
for(j=0;j < 20;j++)
{
for(i = 0; i < 300;i++)
{
printf("Data From Set %d Block %d, Valid %d, Tag %d, LRU %d, Offset %d\n",j,i
,instructions->sets[j]->blocks[i].valid,instructions->sets[j]->blocks[i].tag
,instructions->sets[j]->blocks[i].LRU,instructions->sets[j]->blocks[i].offset);
}
}
return 0;
}
cache* makeCache(cache *makeMe,int numberOfSets,int blocksPerSet)
{
int i = 0;
int j = 0;
for(j=0; j < numberOfSets;j++)
{
cacheSet *newSet = malloc(sizeof(cacheSet) + sizeof(directoryBlock)*blocksPerSet);
for(i = 0; i < blocksPerSet; i++)
{
directoryBlock temp;
temp.LRU = i*j;
temp.tag = i*j;
temp.offset = i*j;
temp.valid = i;
newSet->blocks[i] = temp;
}
makeMe->sets[j] = newSet;
}
return makeMe;
}
You're not allocating space for the cacheSet array, you have 20 cacheSets so try this with the "20 *" added to your lines:
cache *instructions = malloc(sizeof(cache) + 20 *sizeof(cacheSet*));
cache *data = malloc(sizeof(cache) + 20 * sizeof(cacheSet*));
In your main function you're allocating the memory for your cache. Since you have a function dedicated to creating the cache, it should allocate the memory. That function has the parameters to determine the total memory required. If you do it separately, you're repeating that information and require yourself to remember exactly how to allocate the memory. If the function makeCache does it for you, it will save pain later. Just be sure your documentation notes that the makeCache function allocates memory.
Your cache memory is incorrect, but not as pointed out before. Just sizeof(cache) is the right size. This will make room for the int and the cacheSet **. You should then allocate memory for the cacheSet array in each cache. Then you should allocate memory for each directoryBlock in each cacheSet in the cache.... kittens, cats, sacks, and wives...
So all your allocations should just be Thing *t sizof(Thing);
In psuedocode:
cache *c = malloc(sizeof(cache))
for 0 to number of cacheSets:
cacheSet *s = malloc(sizeof(cacheSet))
for 0 to number of blocks:
block *b = malloc(sizeof(block))
//fill in data
JD

Resources