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) );
I'm using an example from https://phoxis.org/2012/07/12/get-sorted-index-orderting-of-an-array/ where he returns the sort indices from a sort of an array, i.e.
3,4,2,6,8 returns 4,3,1,0,2 (+1 for each index in R). This is the equivalent of R's order function
I've translated his/her code to work as a function returning an array of sorted indices. The code gives the correct answer.
keeping track of the original indices of an array after sorting in C has a similar response, but as #BLUEPIXY warns, his solution doesn't work in all circumstances. I need something that will work in all circumstances, including ties.
however, the original author uses a global pointer, which causes a memory leak, and free() doesn't fix it. which I don't know how to do this without the global pointer.
How can I fix this memory leak, or at least return sorted indices in C that will always work?
#include <stdio.h>
#include <stdlib.h>
/* holds the address of the array of which the sorted index
* order needs to be found
*/
int * base_arr = NULL;
/* Note how the compare function compares the values of the
* array to be sorted. The passed value to this function
* by `qsort' are actually the `idx' array elements.
*/
static int compar_increase (const void * a, const void * b) {
int aa = *((int * ) a), bb = *((int *) b);
if (base_arr[aa] < base_arr[bb]) {
return 1;
} else if (base_arr[aa] == base_arr[bb]) {
return 0;
} else {
// if (base_arr[aa] > base_arr[bb])
return -1;
}
}
int * order_int (const int * ARRAY, const size_t SIZE) {
int * idx = malloc(SIZE * sizeof(int));
base_arr = malloc(sizeof(int) * SIZE);
for (size_t i = 0; i < SIZE; i++) {
base_arr[i] = ARRAY[i];
idx[i] = i;
}
qsort(idx, SIZE, sizeof(int), compar_increase);
free(base_arr); base_arr = NULL;
return idx;
}
int main () {
const int a[] = {3,4,2,6,8};
int * b = malloc(sizeof(int) * sizeof(a) / sizeof (*a));
b = order_int(a, sizeof(a) / sizeof(*a));
for (size_t i = 0; i < sizeof(a)/sizeof(*a); i++) {
printf("b[%lu] = %d\n", i, b[i]+1);
}
free(b); b = NULL;
return 0;
}
A straightforward approach without using a global variable can look the following way
#include <stdio.h>
#include <stdlib.h>
int cmp_ptr(const void *a, const void *b)
{
const int **left = (const int **)a;
const int **right = (const int **)b;
return (**left < **right) - (**right < **left);
}
size_t * order_int(const int *a, size_t n)
{
const int **pointers = malloc(n * sizeof(const int *));
for (size_t i = 0; i < n; i++) pointers[i] = a + i;
qsort(pointers, n, sizeof(const int *), cmp_ptr);
size_t *indices = malloc(n * sizeof(size_t));
for (size_t i = 0; i < n; i++) indices[i] = pointers[i] - a;
free(pointers);
return indices;
}
int main( void )
{
const int a[] = { 3,4,2,6,8 };
const size_t N = sizeof(a) / sizeof(*a);
size_t *indices = order_int(a, N);
for (size_t i = 0; i < N; i++) printf("%d ", a[indices[i]]);
putchar('\n');
free(indices);
return 0;
}
The program output is
8 6 4 3 2
As for the memory leak then it is due to overwriting the value of the pointer to redundantly allocated memory.
int * b = malloc(sizeof(int) * sizeof(a) / sizeof (*a));
b = order_int(a, sizeof(a) / sizeof(*a));
The memory allocation does not make sense.
The problem I see is that within main function - you are allocating pointer b some memory -
int * b = malloc(sizeof(int) * sizeof(a) / sizeof (*a));
The next line calls order_int(...) that returns a pointer to already allocated memory -
b = order_int(a, sizeof(a) / sizeof(*a));
Looking at the order_int function -
int * order_int (const int * ARRAY, const size_t SIZE) {
int * idx = malloc(SIZE * sizeof(int));
base_arr = malloc(sizeof(int) * SIZE);
for (size_t i = 0; i < SIZE; i++) {
base_arr[i] = ARRAY[i];
idx[i] = i;
}
qsort(idx, SIZE, sizeof(int), compar_increase);
free(base_arr); base_arr = NULL;
return idx;
}
.. you see that idx has been already been allocated the correct memory.
I would suggest removing the malloc from b - see below.
int * b = NULL;
In order to loop through a regular int array with pointer arithmetic looks like such:
int *p;
int arraySize = 20;
int array[arraySize];
for (p = array; p< array+(sizeof(array)/sizeof(int)); p++){
int random = rand() % 200;
*p = random;
}
for (p = array; p< array+(sizeof(array)/sizeof(int)); p++){
printf("%d\t%x\n", *p, p);
}
for (p = array; p<array+(sizeof(array)/sizeof(int)); p++){
int random = rand() % 200;
*p = random;
}
for (p = array; p< array+(sizeof(array)/sizeof(int)); p++){
printf("%d\t%x\n", *p, p);
}
However, I want to declare:
int *array = (int*) calloc(arraySize, sizeof(int));
I am very confused on how to loop through dynamically allocated memory as opposed to a regular static array.
int *array = (int*)calloc(arraySize, sizeof(int));
int *array_end = array + arraySize;
int* ptr;
for(ptr = array; ptr < array_end; ptr++)
printf("%p\t%d", ptr, *ptr);
I encountered the following question in an interview.
Complete this function to return a reversed array without modifying the function signature or the original array. Note that static data types should not be used here at all.
Assume the arrayLength is a power of 2. i.e 2^n. -> I think this is the trick here.
int* reverse(int *array, int arrayLength){
}
Please help.
Note that I could not really think of a solution to the problem. The interviewer hinted at using 2^n for the puspose, but i could not really think of the solution.
How about this:
int* reverse(int *array, int arrayLength){
if (arrayLength==1) {
int* out=(int*)malloc(sizeof(int));
out[0] = array[0];
return out;
}
int* left = reverse(array+arrayLength/2, arrayLength-arrayLength/2);
int* right = reverse(array,arrayLength/2);
int* out = (int*)realloc(left, sizeof(int)*arrayLength);
memcpy(out+arrayLength/2, right, sizeof(int)*(arrayLength/2));
free(right);
return out;
}
Agree with OP the the hint is "2^n". As with many recursive functions: divide and conquer.
This routine first deals with errant paramters and the simple lengths. Next, divide the length in half and reverse each half. Form the result by concatenating the reversed left and right sub-arrays. First, right, then left.
Usual clean-up follows
#include <string.h>
#include <stdlib.h>
int* reverse(int *array, int arrayLength) {
// Check parameters
if (array == NULL || arrayLength < 0) {
; // TBD HandleBadParameters();
}
// Allocate space for result, not much to do if length <= 1
int *y = malloc(arrayLength * sizeof *y);
if (y == NULL) {
; // TBD HandleOOM();
}
if (arrayLength <= 1) {
memcpy(y, array, arrayLength * sizeof *y);
return y;
}
// Find reverse of the two halves
int halflength = arrayLength / 2;
int *left = reverse(array, halflength);
int *right = reverse(&array[halflength], halflength);
// Append them to the result - in reverse order
memcpy(y, right, halflength * sizeof *y);
memcpy(&y[halflength], left, halflength * sizeof *y);
// Clean-up and return
free(right);
free(left);
return y;
}
int* reverse(int *array, int arrayLength){
if(arrayLength == 0) return array;
int* ret = (int*)malloc(arrayLength*sizeof(int));
for(int i=0;i<arrayLength;i++) ret[i] = array[arrayLength-1-i];
return reverse(ret, 0); // technically recursive
}
Here it is (and works):
int *reverse(int *array, int arrayLength)
{
if (arrayLength > 1) {
int i, n = arrayLength >> 1;
int *m = calloc(n, sizeof(int));
memcpy(m, array, n*sizeof(int));
memcpy(array, array + n, n*sizeof(int));
memcpy(array + n, m, n*sizeof(int));
free(m);
reverse(array, n);
reverse(array+n, n);
} /* for */
return array;
} /* reverse */
it can be done without temporary storage, but you have to iterate a little.
int *reverse(int *a, int al)
{
if (al > 1) {
int i, a1 = al >> 1;
for (i = 0; i < a1; i++) {
int temp = a[i];
a[i] = a[i + a1];
a[i + a1] = temp;
} /* for */
reverse(a, a1);
reverse(a+a1, a1);
} /* for */
return a;
} /* reverse */
but, it would be nicer just to exchange from the boundaries to the middle and do it completely iterative.
int *reverse(int *array, int arrayLength)
{
int a, b;
for (a = 0, b = arrayLength-1; a < b; a++, b--) {
int temp = array[a];
array[a] = array[b];
array[b] = temp;
} /* for */
return array;
} /* reverse */
And just for the ones who asked for a non selfmodifying array, this all-inefficient form:
int *reverse(int *array, int arrayLength)
{
int *a1, *a2;
int *res;
if (arrayLength > 1) {
int l = arrayLength >> 1;
a1 = reverse(array, l);
a2 = reverse(array + l, l);
res = calloc(arrayLength, sizeof(int));
memcpy(res, a2, l*sizeof(int));
memcpy(res+l, a1, l*sizeof(int));
free(a1);
free(a2);
} else {
/* we return always memory alloc'd with malloc() so we have to do this. */
res = malloc(sizeof(int));
*res = array[0];
} /* if */
return res;
} /* reverse */
Well, here's one sneaky way, and it doesn't care what length the array is. Note: I'm assuming you can't introduce a new function, it has to be done all within the existing function
if the length is postive, it allocates memory and makes a copy, then calls reverse again with a negative length and the copy, then if the function is called with a negative length, it reverses the first and last inplace, then recursively calls by moving to the next in the array and shrinks the length till there is nothing left to reverse and then the recursive function unwinds
int* reverse(int *array, int arrayLength){
int* result;
if(arrayLength > 0)
{
result =(int*) malloc((sizeof(int)*arrayLength));
memcpy(result, array, sizeof(int)*arrayLength);
reverse(result, -arrayLength);
return result;
}
else if(arrayLength < -1)
{
int end = (-arrayLength)-1;
int temp = array[end];
array[end] = array[0];
array[0] = temp;
return reverse(array+1, arrayLength+2);
}
return array;
}
Considering that arrayLength is always a power of 2. we will apply the function to the two parts of the array then concat them in the reverse way.
Finaly if the array has only one element, we simply return other array with the same element.
int* reverse(int *array, int arrayLength){
int * newArray = NULL;
if(arrayLength == 1){
newArray = (int *)malloc(sizeof(int));
*newArray = array[0];
} else if(arrayLength == 2){
newArray = (int *)malloc(2 * sizeof(int));
newArray[0] = array[1];
newArray[1] = array[0];
} else {
// apply to first half
int * first = reverse(array, arrayLength / 2);
// apply to second half
int * second = reverse(array + arrayLength / 2, arrayLength / 2);
// allocate space
newArray = (int *) malloc(arrayLength * sizeof(int));
// copy parts in reverse way
memcpy(newArray, second, arrayLength / 2 * sizeof(int));
memcpy(newArray + arrayLength / 2, first, arrayLength / 2 * sizeof(int));
// free allocated space for parts
free(first);
free(second);
}
return newArray;
}
I'll give it a shot.
Knowing that the array is of length 2^n means that it can be safely halved. We call the function recursively on each half until length is 2. At this point we swap the two integers. Think { 2,1,4,3,6,5,8,7 }. When we come back from that, each half is then merged opposite of where it came from ( { 4,3,2,1,8,7,6,5} ). Rinse and repeat.
#include <stdio.h>
#include <stdlib.h>
int * reverse( int* arr, int length )
{
if ( length == 1 )
{
int *result = malloc( sizeof( arr[0] ) );
result[0] = arr[0];
return result;
}
int * result = 0;
if ( length == 2 )
{
result = malloc( sizeof( arr[0] ) * 2 );
result[0] = arr[1];
result[1] = arr[0];
}
else
{
int half_length = length / 2;
// named correctly
int * right = reverse( arr, half_length );
int * left = reverse( arr + half_length, half_length );
result = malloc( sizeof( arr[0] ) * length );
for ( int i = 0; i < half_length; ++i )
{
result[i] = left[i];
result[ i + half_length ] = right[i];
}
free( right );
free( left );
}
return result;
}
int main( void )
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
int length = 8;
int *reversed = reverse( arr, length );
for ( int i = 0; i < length; ++i )
{
printf( "%d %d\n", arr[i], reversed[i] );
}
free( reversed );
return 0;
}
for all integer arrays with more than 2 elements.
The basic idea is to swap elements from both ends untill the number of elements remaining is 1.
int* reverse_array(int* array, int arrayLength)
{
if(arrayLength <2)
{
return NULL;
}
else
{
int *array1 = NULL;
int *array2 = NULL;
array1 = malloc(arrayLength*sizeof(int));
memcpy(array1,array,arrayLength*sizeof(int));
/*swap the start and end*/
swap(array1,(array1+arrayLength-1));
/* swap the next pair */
array2 = reverse_array(array1+1,arrayLength-2);
memcpy(array1+1,array2,(arrayLength-2)*sizeof(int));
if(array2!= NULL)
{
free(array2);
}
return array1;
}
}
I'm trying to allocate a struct array inside a function, but when I return to main it's like the memory that I just allocated has been overwritten. That's my example code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Class {
int students;
Person * N;
};
struct Person
{
char * name;
int age;
};
void allocation(struct Class ** myclasspointer)
{
struct Class *mytempstruct= malloc(sizeof *mytempstruct);
mytempstruct -> students = 10;
char *n= "My name is...?";
mytempstruct -> N = malloc (sizeof (mytempstruct -> N) * 10);
for (i = 0; i < 10; i++) {
mytempstruct -> N[i].age = i;
mytempstruct -> N[i].name = malloc (sizeof (char) * (strlen(n));
strncpy (N[i].name, n, strlen(n));
}
*myclasspointer = mytempstruct;
}
int main(void)
{
int i;
struct class * MyClass;
allocation(&MyClass);
for (int i = 0; i < MyClass.students; i++)
Prinf("Student %s, age %d: %d \n", MyClass->N[i].name, MyClass->N[i].age);
for (int i = 0; i < MyClass->students; i++)
free(MyClass->N[i]);
free (MyClass);
return 0;
}
Once I go back to main, only some values are as they should. I also tryed to change:
void allocation(struct Class ** myclasspointer)
{
struct Class *mytempstruct= malloc(sizeof *mytempstruct);
char *n= "My name is...?";
mytempstruct -> N = malloc (sizeof (mytempstruct -> N) * 10);
for (i = 0; i < 10; i++) {
mytempstruct -> N[i].age = i;
mytempstruct -> N[i].name = malloc (sizeof (char) * (strlen(n));
}
*myclasspointer = mytempstruct;
}
to:
void allocation(struct Class ** myclasspointer)
{
myclasspointer= malloc(sizeof *myclasspointer);
char *n= "My name is...?";
myclasspointer-> N = malloc (sizeof (myclasspointer-> N) * 10);
for (i = 0; i < 10; i++) {
mytempstruct -> N[i].age = i;
mytempstruct -> N[i].name = malloc (sizeof (char) * (strlen(n));
}
}
But I have the same result.
First you need a forward declaration of person. Then change
mytempstruct -> N = malloc (sizeof (mytempstruct -> N) * 10);
^will give the size of pointer instead of structure `person`
to
mytempstruct -> N = malloc (sizeof (struct person) * 10);
mytempstruct -> N[i].name = malloc (sizeof (char) * (strlen(n)) );
strncpy (N[i].name, n, strlen(n));
is wrong you want:
mytempstruct -> N[i].name = malloc (sizeof (char) * (strlen(n)+1) );
strncpy (N[i].name, n, strlen(n)+1);
for space for the null character.