So I have a program and its work fine.
#include <stdio.h>
#include <stdlib.h>
#define STACKDEFSIZE 1
typedef struct
{
unsigned long int maxsize;
unsigned long int cursize;
unsigned long int* arr;
} stack;
stack* create_stack()
{
stack* res = (stack*)malloc(sizeof(stack));
res->arr = malloc(sizeof(long) * STACKDEFSIZE);
res->maxsize = STACKDEFSIZE;
res->cursize = 0;
return res;
}
void push(stack* st, int val)
{
if (st->cursize == st->maxsize)
{
unsigned long int* old = st->arr;
st->maxsize *= 2;
st->arr = malloc(sizeof(unsigned long int) * st->maxsize);
int i;
for(i = 0; i < st->cursize; i++)
st->arr[i] = old[i];
free(old);
}
st->arr[st->cursize] = val;
st->cursize += 1;
}
int main() {
stack* s = create_stack();
int i;
for(i = 0; i < 10000; i++)
{
push(s, i);
}
return 0;
}
But if I change function 'push' to use realloc instead of malloc and free, program crash with message " Error in `./t': realloc(): invalid next size: 0x0000000001031030
Aborted"
void push(stack* st, int val)
{
if (st->cursize == st->maxsize)
{
st->maxsize *= 2;
st->arr = realloc(st->arr, st->maxsize);
}
st->arr[st->cursize] = val;
st->cursize += 1;
}
Also valgrind print message 'Invalid write of size 8' when I trying to use realloc.
What I doing wrong?
I use gcc and Debian Jessie x86_64.
You are passing the wrong size to realloc. As a consequence, your program runs into undefined behavior in no time.
Use:
st->arr = realloc(st->arr, sizeof(*st->arr)*st->maxsize);
Related
I have this kind of code
typedef struct {
int x;
int y;
} Test;
Test* getTest(int *length) {
Test *toReturn = malloc(sizeof(Test));
// Some operations with realloc
return toReturn;
}
void printTest(Test *arrTest, int length) {
for(int i = 0; i < length; i++) {
// Some operations
}
}
int main() {
int testlength = 0;
Test *myTest = getTest(&testlength);
printTest(myTest, testLength) // Gives random numbers
}
Don't know why it gives random numbers, when I'm in the main tho (the whole code) it does not give these kinds of errors
Made minor changes to the code, see below:
#include <stdio.h>
typedef struct {
int x;
int y;
} Test;
Test* getTest(int *length) {
Test *toReturn = (Test *)malloc(sizeof(Test));
// Some operations with realloc
return toReturn;
}
void printTest(Test *arrTest, int length) {
printf("%d ", length);
for(int i = 0; i < length; i++) {
// Some operations
}
}
int main() {
int tlen = 0;
Test *myTest = getTest(&tlen);
printTest(myTest, tlen); // Gives random numbers
printf("....Exit....");
return 0;
}
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 *.
Hi I have to do a simulation of disk for my university.
I got 2 file :
tttfs.h :
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
typedef struct _disk disk;
typedef struct _block block;
struct _block{
uint8_t *unBlock;
};
struct _disk{
int id;
block *diskBlock;
};
tfs_create.c :
#include "tttfs.h"
uint8_t little[4];
int tttfs_create(int size, char *name);
void inttolitend(uint32_t x, uint8_t* lit_int);
int main(){
tttfs_create(7, "disk.tfs");
}
int tttfs_create(int size, char *name){
FILE *f = NULL;
if ((f = fopen(name, "wb"))!=NULL)
{
disk *d = malloc(sizeof(disk));
d->diskBlock = malloc(1024);
d->id = 1;
int i;
for(i = 0; i<size; i++){
printf("%d\n", i);
d->diskBlock[i].unBlock = malloc(1024); //I got the segmentation fault here
}
inttolitend(size, little);
for(i = 0; i<4; i++){
d->diskBlock[0].unBlock[i] = little[i];
}
for(i = 0; i<size; i++){
fwrite(&d->diskBlock[i],1024,1,f);
}
}
else
printf("Erreur\n\n");
return 0;
}
void inttolitend(uint32_t x, uint8_t* lit_int){
lit_int[3] = (uint8_t)x / (256*256*256);
lit_int[2] = (uint8_t)(x % (256*256*256)) / (256*256);
lit_int[1] = (uint8_t)((x % (256*256*256)) % (256*256)) / 256;
lit_int[0] = (uint8_t)((x % (256*256*256)) % (256*256)) % 256;
}
I want to write in a file a number of block (here 7), so I do malloc on size of my disk struct and then I do a malloc on diskBlock to make a table d->diskBlock[0].unBlock = malloc(1024); but not for more. how could I do a block[size] with my struct ? (I'm not good in c)
I think you should change this line
d->diskBlock = malloc(1024);
to
d->diskBlock = malloc(sizeof(block) * size);
And, this
d->diskBlock[i].unBlock = malloc(1024);
to
d->diskBlock[i].unBlock = malloc(sizeof(uint8_t) * 4);
Searched around for one hour. I guess I'd better post the question here.
I simplify the code. The segfault is in the function initMyStruct.
#include "stdlib.h"
typedef struct {
int * arr1;
int * arr2;
} myStruct;
void allocMyStruct (myStruct * a, int num) {
a = malloc(sizeof(myStruct));
a->arr1 = malloc(10*sizeof(int));
a->arr2 = malloc(10*num*sizeof(int));
}
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;
}
void freeMyStruct (myStruct * a, int num) {
int i;
for (i = 0; i < 10; i++) free(a->arr1);
for (i = 0; i < 10*num; i++) free(a->arr2);
free(a);
}
int main (void) {
int num = 3;
myStruct * a;
allocMyStruct (a, num);
initMyStruct (a, num);
freeMyStruct (a, num);
return 1;
}
Because you're not keeping the pointer to the newly allocated memory, instead you use an uninitialized pointer and getting undefined behavior.
You pass the a variable into allocMyStruct(), but that call is (like all others) by value, so the new value being assigned to it inside the function does not affect the value of a in main().
Change it so that allocMyStruct() either returns the new pointer value, or takes a pointer to the pointer. I would prefer the former, it's cleaner and using function return values often leads to better code:
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;
}
The above code also streamlines the memory allocation, doing it all in one big malloc() call which is then "sliced" into the three parts you actually need.
If the size of arr1 is always 10 by the way, there's no point in having it dynamically allocated, it should just be int arr1[10]; in the struct declaration.
a is used uninitialized, change to:
myStruct * allocMyStruct (int num) {
myStruct *a;
a = malloc(sizeof(myStruct));
a->arr1 = malloc(10*sizeof(int));
a->arr2 = malloc(10*num*sizeof(int));
return a;
}
myStruct * a = allocMyStruct(num);
Also, there is no need to loop in your free function
void freeMyStruct (myStruct * a, int num) {
int i;
for (i = 0; i < 10; i++) free(a->arr1);
for (i = 0; i < 10*num; i++) free(a->arr2);
free(a);
}
Must be
void freeMyStruct (myStruct * a) {
free(a->arr1);
free(a->arr2);
free(a);
}
When you call void allocMyStruct (myStruct * a, int num) the a pointer will be passed as a value and the a parameter is a local copy of your pointer from main , after you change the local a in any of your three functions, it will not change in main.
For this you have to use double pointer as a function argument, so those functions will get an address of a pointer so they can modify it.
#include "stdlib.h"
typedef struct {
int * arr1;
int * arr2;
} myStruct;
void allocMyStruct (myStruct ** a, int num) {
*a = malloc(sizeof(myStruct));
(*a)->arr1 = malloc(10*sizeof(int));
(*a)->arr2 = malloc(10*num*sizeof(int));
}
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;
}
void freeMyStruct (myStruct ** a, int num) {
free((*a)->arr1);
free((*a)->arr2);
free(*a);
*a = NULL;
}
int main (void) {
int num = 3;
myStruct * a;
allocMyStruct (&a, num);
initMyStruct (&a, num);
freeMyStruct (&a, num);
return 1;
}
EDIT: Alter Mann is right about multiple freeing of the same address, on linux you would get instant crash for double freeing. And he has a simpler solution.
I'm trying to come up with a rudimentary radix sort (I've never actually seen one, so I'm sorry if mine is awful), but I am getting an EXC_BAD_ACCESS error on the line link = *(link.pointer);. My C skills aren't great, so hopefully someone can teach me what I'm doing wrong.
I'm using XCode and ARC is enabled.
Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define ARRAY_COUNT 10
#define MAX_VALUE 1000000
#define MODULO 10.0f
typedef enum
{
false,
true
} bool;
typedef struct linkedListStruct
{
int value;
struct linkedListStruct *pointer;
} LinkedList;
void radixSort(int *array);
bool arraySorted(int *array);
int * intArray(int minValue, int maxValue);
int main(int argc, const char * argv[])
{
int *sortingArray = intArray(0, MAX_VALUE);
radixSort(sortingArray);
printf("Array %s sorted", arraySorted(sortingArray) ? "" : "not");
return 0;
}
void radixSort(int *array)
{
int numberOfIterations = (int)ceilf(log(MAX_VALUE)/log(MODULO));
for(int n = 0; n < numberOfIterations; n++)
{
LinkedList *linkedListPointers[(int)MODULO] = {0};
int i = ARRAY_COUNT;
while(i--)
{
int location = (int)floor((array[i] % (int)powf(MODULO, n + 1))/powf(MODULO, n));
LinkedList link = { array[i], NULL };
link.pointer = linkedListPointers[location];
linkedListPointers[location] = &link;
}
int location = 0;
for(int pointerSelection = 0; pointerSelection < MODULO; pointerSelection++)
{
if(linkedListPointers[pointerSelection])
{
LinkedList link = { 0, linkedListPointers[pointerSelection] };
linkedListPointers[pointerSelection] = NULL;
while(link.pointer)
{
link = *(link.pointer);
array[location++] = link.value;
}
}
}
}
}
bool arraySorted(int *array)
{
int i = ARRAY_COUNT;
while(--i)if(array[i - 1] > array[i])break;
return !i;
}
int * intArray(int minValue, int maxValue)
{
int difference = maxValue - minValue;
int *array = (int *)malloc(sizeof(int) * ARRAY_COUNT);
int i;
for(i = 0; i < ARRAY_COUNT; i++)
{
array[i] = rand()%difference + minValue;
}
return array;
}
Also, if someone wants to suggest improvements to my sort, that would also be appreciated.
The problem came from how I was allocating the linked list. I changed
LinkedList link = { array[i], NULL };
link.pointer = linkedListPointers[location];
to
LinkedList *link = malloc(sizeof(LinkedList));
link->value = array[i];
link->pointer = linkedListPointers[location];
In the first example, the pointer to link remained the same through each loop iteration (I wasn't aware it would do that), so I needed to make the pointer point to a newly allocated memory chunk.
EDIT:
Changing that also had me change from
while(link.pointer)
{
link = *(link.pointer);
array[location++] = link.value;
}
to
while(linkPointer)
{
link = *linkPointer;
array[location++] = link.value;
linkPointer = link.pointer;
}