free(): invalid next size (fast) for resizable vector - c

I'm trying to implement a resizable vector in C without using the realloc and calloc functions. However, when I try to push a lot of values to the back of the array, I get a free(): invalid next size error. How can I remedy this?
I tried freeing the array right before I re-malloc it( the commented out block) but that causes a seg fault rather than the current error.
typedef struct {
size_t size;
size_t maxsize;
int* array;
}
vector_int_t;
// Push a new value into the vector_int_t, allocate just enough memory if
// the internal array is full.
void vector_int_push_back_v1( vector_int_t* this, int value )
{
if( this->size == this->maxsize ) {
int* temp = malloc( 4 * (sizeof( this->maxsize)+1) );
size_t j = 0;
for( size_t i = 0; i < this->maxsize; i++ ) {
temp[j] = this->array[i];
j++;
}
temp[this->size] = value;
/*if( this->size == 0 ) {
this->array = malloc( 4 * (sizeof(this->maxsize)+2));
this->size++;
this->maxsize++;
size_t z = 0;
for( size_t y = 0; y < this->maxsize; y++ ) {
this->array[z] = temp[y];
z++;
}
}
else {
free( this->array );*/
this->array = malloc( 4 * (sizeof(this->maxsize)+2) );
this->size++;
this->maxsize++;
size_t h = 0;
for( size_t k = 0; k < this->maxsize; k++ ) {
this->array[h] = temp[k];
h++;
}
free( temp );
}
else {
this->size++;
this->maxsize++;
this->array[this->size - 1] = value;
}
}

This error typically happens when you write out of bounds of the allocated memory.
A very likely culprit is the use of sizeof in e.g. malloc( 4 * (sizeof( this->maxsize)+1) ).
If you want to allocate this->maxsize + 1 elements, you should use just that not sizeof.
But you should use sizeof to get the size of each element (e.g. sizeof *temp).
So the statement
int* temp = malloc( 4 * (sizeof( this->maxsize)+1) );
should really look like
int* temp = malloc( sizeof *temp * (this->maxsize+1) );

Related

How to correctly initialise a struct in C

I'm working on a small project in C and I want to allocate structs in a function and add them to an array of structs.
For some reason, when I go to print the contents of the array of structs, I appear to start printing from unallocated memory.
A minimum working example is provided below:
#include <stdio.h>
#include <stdlib.h>
// This struct simply stores a list and its size
struct list {
int* values;
size_t size;
};
// This function initialises an array of lists
// of size len, which each list (i.e. list.values)
// having a size of list_len
// `lists` is an array of pointers to lists
void list_init(struct list** lists, size_t len, size_t list_len) {
for (size_t i = 0; i < len; i++) {
struct list list;
list.values = malloc(sizeof(int) * list_len);
list.size = list_len;
lists[i] = &list;
}
}
void main() {
int len = 3;
struct list* lists[len];
list_init(lists, len, 5);
// Print lists
for (size_t i = 0; i < len; i++) {
printf("list %zu: ", i);
printf("size: %zu\n", lists[i]->size);
for (size_t j = 0; j < 5; j++) { // Using 5 instead of lists[i]->size for obvious reasons
printf("%d ", lists[i]->values[j]);
}
printf("\n");
}
}
The output I would expect from this is:
list 0: size: 5
0 0 0 0 0
list 1: size: 5
0 0 0 0 0
list 2: size: 5
0 0 0 0 0
but instead I get:
list 0: size: 5
0 0 0 0 0
list 1: size: 140727488332736
0 0 0 0 0
list 2: size: 140727488332736
0 0 0 0 0
which is a pretty clear sign that I'm accessing memory that I'm not supposed to.
I noticed that rather than declaring the list with struct list list;, if I declare the list by allocating memory to a pointer with struct list* list = malloc(sizeof(struct list)); the program gives the expected output. Why is that? If I want to create the object, rather than a pointer, how can I do that properly.
P.S.: I am aware that I could just initialise list as a pointer. This question is mostly asking why can't I initialise it as an object
You save the references to the same local variable and it is an UB. Also malloced memory is lost. Your main is also wrong.
I would do it this way (calloc is used as in main you print not initialized allocated memory):
typedef struct list {
size_t size;
int values[];
}list;
list **list_init(list **array, size_t size, size_t list_len)
{
list **wrk;
if(!array) wrk = malloc(sizeof(*wrk) * size);
else wrk = array;
if(wrk)
for (size_t i = 0; i < size; i++) {
list *list = calloc(1, sizeof(*list) + list_len * sizeof(list -> values[0]));
/* check for allocation errors!!!! */
list -> size = list_len;
wrk[i] = list;
}
return wrk;
}
int main(void) {
size_t len = 3;
list **lists;
/* if you pass NULL it will create the list of lists itself */
lists = list_init(NULL, len, 5);
/* check for allocation errors!!!! */
// Print lists
for (size_t i = 0; i < len; i++) {
printf("list %zu: ", i);
printf("size: %zu\n", lists[i]->size);
for (size_t j = 0; j < 5; j++) { // Using 5 instead of lists[i]->size for obvious reasons
printf("%d ", lists[i]->values[j]);
}
printf("\n");
}
for (size_t i = 0; i < len; i++) free(lists[i]);
free(lists);
}
https://godbolt.org/z/9TPe1sM1a
These statements within the function list_init
struct list list;
//...
lists[i] = &list;
does not make a sense because the local object list will not be alive after exiting the function. So you will have an array of invalid pointers of the type struct list *.
You need to allocate dynamically each object of the type struct list that will be pointed to by an element of the array.
The function can be declared and defined for example the following way
size_t list_init( struct list **lists, size_t len, size_t list_len )
{
size_t count = 0;
for ( size_t i = 0; i < len; i++ )
{
lists[i] = malloc( sizeof( struct list ) );
if ( lists[i] != NULL )
{
++count;
lists[i]->size = 0;
lists[i]->values = malloc( sizeof( int ) * list_len );
if ( lists[i]->values != NULL ) lists[i]->size = list_len;
}
}
return count;
}
Also as the function does not initialize the allocated array pointed to by the data member values then this loop in main
for (size_t j = 0; j < 5; j++) { // Using 5 instead of lists[i]->size for obvious reasons
printf("%d ", lists[i]->values[j]);
}
will invoke undefined behavior.
You could zero initialize the arras by using calloc instead of malloc. For example
lists[i]->values = calloc( list_len, sizeof( int ) );
And pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
Here is your updated program.
#include <stdio.h>
#include <stdlib.h>
// This struct simply stores a list and its size
struct list
{
int* values;
size_t size;
};
size_t list_init( struct list **lists, size_t len, size_t list_len )
{
size_t count = 0;
for ( size_t i = 0; i < len; i++ )
{
lists[i] = malloc( sizeof( struct list ) );
if ( lists[i] != NULL )
{
++count;
lists[i]->size = 0;
lists[i]->values = calloc( list_len, sizeof( int ));
if ( lists[i]->values != NULL ) lists[i]->size = list_len;
}
}
return count;
}
int main(void)
{
size_t len = 3;
struct list* lists[len];
list_init(lists, len, 5);
// Print lists
for ( size_t i = 0; i < len; i++ )
{
printf( "list %zu: ", i );
if ( lists[i] != NULL )
{
printf( "size: %zu\n", lists[i]->size );
for (size_t j = 0; j < lists[i]->size; j++)
{
printf( "%d ", lists[i]->values[j] );
}
printf("\n");
}
}
return 0;
}
The program output is
list 0: size: 5
0 0 0 0 0
list 1: size: 5
0 0 0 0 0
list 2: size: 5
0 0 0 0 0
Of course you need to add a code to your program that will free all the allocated memory in the function list_init.

How to properly free memory inside a function that increases the rows of a 2D char array

I have a function that increases the rows of a 2D char array, which does contain elements in it. Am I supposed to free the memory after using calloc? How do I do that inside the function? I am getting memory leaks and I think it may be due to me not using free.
char **decode_structure;
void make_row_decode_structure_bigger(int rows){
//printf("inside the making the rows bigger \n");
int max_rows = rows+1;
char **store = realloc( decode_structure, sizeof *decode_structure * (rows + 1) );
//printf("after a store has been assigned\n");
if (store){
decode_structure = store;
for(size_t i = 0; i < 1; i++ ){
decode_structure[rows + i] = calloc(15, sizeof(char));
decode_structure[rows + i][0] = '\0';
}
}
//printf("end of making the rows increase\n");
return;
}
//in main()
decode_structure = (char**)calloc( 2, sizeof(char*) );
for(size_t i = 0; i < 2; i++){
decode_structure[i] = calloc(15, sizeof(char));
decode_structure[i][0] = '\0';
}
here is the error message that showed up:
* Error in `./prog': free(): corrupted unsorted chunks: 0x0000000001937010 *

Contiguous memory allocation for 2D array --- freeing the memory

I am facing a heap crash during free() when I run this program, but I am successful if I do debug using F10 (in Visual studio 2010).
My piece of code:
The below code is used to free. Can someone please explain deallocation for 2D array in this case?
void Deallocate2D ( SINT32 **pAccess, UINT8 i_ubyNoOfRows )
{
int i;
UINT8 *elem;
if ( NULL == pAccess )
{
printf ( "%d>Invalid Params\n", __LINE__ );
return;
}
printf ( "\nDeallocate 2D Array..................\n" );
/* Include the code to deallocate the 2D array */
{
free(pAccess);
}
}
The below code is used for memory allocation:
SINT32 Allocate2D (
SINT32 ***pAccess,
UINT8 i_ubyNoOfRows,
UINT8 i_ubyNoOfCols )
{
SINT32 nResult = -1;
SINT32 **pAc = NULL;
UINT8 *pubyPositioner;
UINT32 unTotalSize;
int i;
//unTotalSize = i_ubyNoOfRows * i_ubyNoOfCols;
printf ( "\nAllocate 2D Array..................\n" );
/* Include the code to allocate the 2D array */
{
/*Contiguous memallocation pAc*/
pAc = (SINT32**)malloc(sizeof(SINT32*) * i_ubyNoOfRows);
if(pAc)
pubyPositioner = (UINT8*)malloc(sizeof(UINT8) * i_ubyNoOfCols);
if(pubyPositioner)
for(i = 0; i < i_ubyNoOfCols; ++i)
pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols);
*pAccess = pAc;
/*Non contugious allocation*/
/*
pAc = (SINT32**)malloc(sizeof(SINT32*) * i_ubyNoOfRows );
*pAccess = pAc;
if(pAc)
for(i= 0; i < i_ubyNoOfRows; ++i){
pAc[i] = (SINT32*)malloc(sizeof(SINT32*) + (i * i_ubyNoOfRows) );
if(pAc[i])
for(j = 0; j < i_ubyNoOfCols; ++j)
pAc[i][j] = (UINT8)malloc(sizeof(UINT8) + (i_ubyNoOfRows * i_ubyNoOfCols) );
}
*/
if(*pAccess != NULL)
nResult = 0;
}
if ( NULL == pAccess )
{
printf ( "%d>Invalid Params\n", __LINE__ );
return -1;
}
return nResult;
}
The code to fill array and print array:
SINT32 Fill2D (
SINT32 **pnAccess,
SINT32 *pnData,
UINT8 i_ubyNoOfRows,
UINT8 i_ubyNoOfCols )
{
SINT16 wRIndex, wCIndex, wDataIndex = 0;
printf ( "\nFill 2D Array..................\n" );
/* Include the code to fill the 2D array with the 1D values */
{
for(wRIndex = 0 ; wRIndex < 3; ++wRIndex)
for(wCIndex = 0; wCIndex < 3; ++wCIndex)
pnAccess [wRIndex][wCIndex] = pnData[wDataIndex++];
}
if ( ( NULL == pnAccess ) \
|| ( NULL == pnData ) )
{
printf ( "%d>Invalid Params\n", __LINE__ );
return -1;
}
return 0;
}
SINT32 Print2D (
SINT32 **pnAccess,
UINT8 i_ubyNoOfRows,
UINT8 i_ubyNoOfCols )
{
SINT16 wRIndex, wCIndex;
if ( NULL == pnAccess )
{
printf ( "%d>Invalid Params\n", __LINE__ );
return -1;
}
printf ( "\n2D Array..................\n\n" );
/* Include the code to Print the 2D array in matrix format */
{
for(wRIndex = 0 ; wRIndex < i_ubyNoOfRows; ++wRIndex)
{
if(wRIndex % 2 == 0)
printf("\n");
for(wCIndex = 0; wCIndex < i_ubyNoOfCols; ++wCIndex)
printf("%d ", pnAccess[wRIndex][wCIndex]);
}
}
return 0;
}
The below code is kind of entry point:
void Test2DArray ( void )
{
SINT32 **pnData = NULL;
SINT32 nData1[] = { 10, 15, 20, 15, 20, 25, 10, 25, 20 };
SINT32 nData2[] = { 70, 75, 80, 65, 90, 25, 30, 35, 80 };
printf ( "\n==================================\n" );
printf ( "Test 2D Array..................\n" );
printf ( "==================================\n\n" );
if ( Allocate2D( &pnData, 3, 3 ) != -1 )
{
if ( Fill2D( pnData, nData1, 3, 3 ) != - 1 )
{
if ( NULL != pnData )
{
Print2D ( pnData, 3, 3 );
Deallocate2D ( pnData, 3 );
}
}
}
if ( Allocate2D( &pnData, 3, 3 ) != -1 )
{
if ( Fill2D( pnData, nData2, 3, 3 ) != - 1 )
{
if ( NULL != pnData )
{
Print2D ( pnData, 3, 3 );
Deallocate2D ( pnData, 3 );
}
}
}
}
/*Contiguous memallocation pAc*/
pAc = (SINT32**)malloc(sizeof(SINT32*) * i_ubyNoOfRows);
if(pAc)
pubyPositioner = (UINT8*)malloc(sizeof(UINT8) * i_ubyNoOfCols);
if(pubyPositioner)
for(i = 0; i < i_ubyNoOfCols; ++i)
pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols);
This is not contiguous memory allocation! It is a pointer-based lookup table which is allocated in one segment, pointing at a chunk of memory allocated in another segment.
Correct code for allocating a true 2D array would be:
SINT32 (*pAc)[ubyNoOfCols] = malloc( sizeof(SINT32[i_ubyNoOfCols][i_ubyNoOfRows]) );
...
free(pAc);
Note that this will only compile on a C compiler, so you can't use Visual Studio.
Can someone please explain deallocation for 2D array in this case?
free(pAccess);
Looks like the code only deallocates the pointer lookup table and not the actual data. So I suppose that is a bug: the code contains memory leaks.
Lets take a look at your allocation code:
pAc = (SINT32**)malloc(sizeof(SINT32*) * i_ubyNoOfRows);
if(pAc)
pubyPositioner = (UINT8*)malloc(sizeof(UINT8) * i_ubyNoOfCols);
if(pubyPositioner)
for(i = 0; i < i_ubyNoOfCols; ++i)
pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols);
So, you are first allocating memory for i_ubyNoOfRows pointers. This is fine.
Then you proceed to allocate i_ubyNoOfCols bytes, (3 bytes in your test case), but you need space for i_ubyNoOfCols*i_ubyNoOfRows integers (3*3*4 = 36 bytes in your test case, assuming int is a 32-bit type).
When you proceed to initialize your memory, you trod on data vital for malloc() and free() to function properly.
A telltale sign of one half of your mistake is the cast in the line pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols);. It shows that you used a wrong type for pubyPostitioner.
Ps: You have two 3s hardcoded in Fill2D(), even though this function gets the correct width and height passed as arguments.
In my question,I wanted to allocate memory for 2D array then free it.
After some study, i have explained my understanding as below
Allocate memory using array of pointers
double **p;
int i;
p= malloc(rows * sizeof(*p));
for(i= 0; i<rows;++i)
p[i] = malloc(cols * sizeof(double));
...
...
for(i=0;i<rows;i++)
free(p[i]);
free(p);
allocation using pointer lookup table
double **p;
double *elem;
elem = malloc(rows * cols * sizeof(double));
p = malloc(cols * sizeof(double*));
for (i = 0; i<rows;++i)
p[i] = elem + ( i*cols);
free(p);
Contiguous Allocation
double **p;
p = malloc( rows * cols * sizeof(double*));
/*Accessing / printing values ... assume values are assinged to this array*/
for(i=0; i <rows; ++i)
for(j = 0; j< cols; ++j)
printf("%d",p[j + (i * cols)]);
free(p)

Assign pointer to block reserved with malloc

Based on this answer: https://stackoverflow.com/a/19765782/1606345
#include <stdlib.h>
typedef struct {
int *arr1;
int *arr2;
} myStruct;
myStruct *allocMyStruct(int num)
{
myStruct *p;
if ((p = malloc(sizeof *p +
10 * sizeof *p->arr1 +
10 * num * sizeof *p->arr2)) != NULL)
{
p->arr1 = (int *)(p + 1);
p->arr2 = p->arr1 + 10;
}
return p;
}
void initMyStruct(myStruct * a, int num)
{
int i;
for (i = 0; i < 10; i++) a->arr1[i] = 0;
for (i = 0; i < 10 * num; i++) a->arr2[i] = -1;
}
int main (void)
{
int num = 3;
myStruct *a = allocMyStruct(num);
initMyStruct(a, num);
free(a);
return 1;
}
It is safe to assign p->arr1 to the address of (p + 1)?
p->arr1 = (int *)(p + 1);
You have a fundamental problem here in how you are thinking about struct allocation.
When you malloc a struct, you malloc the sizeof that struct, you don't malloc for the arrays it will contain, those need to be allocated separately. To do this your code should look more like:
myStruct *allocMyStruct(int num)
{
myStruct *p = malloc( sizeof( myStruct ) );
if( p != NULL )
{
p->arr1 = malloc( sizeof( int ) * 10 ); // p->arr1 now points to an array of 10 elements
p->arr2 = malloc( sizeof( int ) * 10 * num ); // p->arr2 now points to an array of 10 * num elements
}
return p;
}
Keep in mind when you free this you will need to free the arrays individually as well so if your pointer the myStruct was a:
free( a->arr1 );
free( a->arr2 );
free( a );

Getting runtime error when i access (table->array[i][i]).min = (table->array[i][i]).max = arr[i];

I am using DP to fill a table which contains maximum & minimum item from index i to index j in an array. Whether this approach is efficient or not, is not an issue to me.
Consider the below code snippet:
typedef struct Slot
{
int min;
int max;
}Slot;
typedef struct Table
{
Slot* *array;
int size;
}Table;
Table* createTable( int size )
{
Table* table = malloc( sizeof( Table ) );
if( !table )
return NULL;
table->array = ( Slot(*)[size] ) malloc( size * size * sizeof( Slot ) );
if( !(table->array) )
return NULL;
table->size = size;
return table;
}
void foo( int arr[], int size )
{
Table* table = createTable( size );
if( table == NULL )
{
printf( "Out of memory" );
return;
}
int i;
for( i = 0; i < size; ++i )
(table->array[i][i]).min = (table->array[i][i]).max = arr[i]; <----------
}
I am getting runtime error. When i comment the below two statements, it runs fine.
for( i = 0; i < size; ++i )
(table->array[i][i]).min = (table->array[i][i]).max = arr[i]; <----------
Why it is showing runtime error?
The malloc of your 2D array Slot is wrong:
table->array = ( Slot(*)[size] ) malloc( size * size * sizeof( Slot ) );
instead of this you should do this:
table->array = (Slot**) malloc(sizeof(Slot*));
for (int i = 0; i < ArraySizeX; i++)
table->array[i] = (Slot*) malloc(ArraySizeY*sizeof(Slot));
or if you wish to do it in one malloc call, however then only have a Slot* in your Table:
table->array = (Slot*) malloc(SizeX * SizeY * Sizeof(Slot));
This will allocate your double array properly.
Then also, this construct:
for( i = 0; i < size; ++i )
(table->array[i][i]).min = (table->array[i][i]).max = arr[i];
you should really do one assignment at a time:
for( i = 0; i < sizeX; ++i )
{
(table->array[i][i]).max = arr[i];
(table->array[i][i]).min = (table->array[i][i]).max;
}

Resources