I have a simple byte array structure:
typedef struct ByteArray {
int size;
uint8_t* arr;
} ByteArray;
that I'm creating like this:
ByteArray* byte_array_create(size_t size) {
ByteArray* a = malloc(sizeof(ByteArray));
a->size = size;
a->arr = (uint8_t*)malloc(a->size);
return a;
}
later I'm using this in another module like this:
static void rom_set_prg_bank(Rom* r, iNESHeader* h, FILE* romFile) {
r->PRG = byte_array_create(h->numPRG * 0x4000);
size_t size = fread(r->PRG->arr, r->PRG->size, 1, romFile);
byte_array_print(r->PRG->arr);
}
now inside of rom_set_prg_bank() r->PRG->arr has it's allocated memory and everything looks good. I can look through the memory block and see everything. As soon as I get into byte_array_print() I get a bad access error.
void byte_array_print(ByteArray* a) {
for(int i = 0; i < a->size; i++) {
// EXC_BAD_ACCESS (code=EXC_I386_GPFLT) happens
// when I try to access any of the values in the
// byte array
printf(a->arr[i]);
}
}
Can anyone see what I'm doing wrong?
byte_array_print(r->PRG->arr);
passes the allocated buffer defined as an element of the ByteArray struct, but byte_array_print expects a pointer to the full ByteArray struct, not the buffer. Fix it with:
byte_array_print(r->PRG)
Related
Really stuck on the following problem. I'm creating a dynamic array, but when I re-size (for which the logic is creating a new array, copying the values of the old array into the new array, and then deleting old array). I keep getting a memory error when trying to free the memory of old array. See below; I feel like it's something obvious but my eyes just can't see it right now.
Struct to hold the array:
struct DynArr
{
TYPE *data; /* pointer to the data array */
int size; /* Number of elements in the array */
int capacity; /* capacity ofthe array */
};
Function to create a new array:
DynArr *newDynArr(int cap)
{
assert(cap > 0);
DynArr *r = (DynArr *)malloc(sizeof(DynArr));
assert(r != 0);
initDynArr(r, cap);
return r;
}
Initializing the array:
void initDynArr(DynArr *v, int capacity)
{
assert(capacity > 0);
assert(v != 0);
v->data = (TYPE *)malloc(sizeof(TYPE) * capacity);
assert(v->data != 0);
v->size = 0;
v->capacity = capacity;
}
Function to resize the array:
void _dynArrSetCapacity(DynArr *v, int newCap)
{
struct DynArr *newData;
/*new array to hold new values*/
newData = newDynArr(newCap);
///*Intialize the new array*/
initDynArr(newData,newCap);
/*Copy values from old array into new array*/
for (int a = 0; a < v->size; a++)
{
addDynArr(newData, v->data[a]);
}
/*Free the old array, data and array, Cant get this to work*/
/*freeDynArr(v) */
/*Have v point to new array*/
v = newData;
}
And function to free the memory, which is throwing me the error:
void freeDynArr(DynArr *v)
{
if (v->data!= 0)
{
free(v->data); /* free the space on the heap */
v->data = 0; /* make it point to null */
}
v->size = 0;
v->capacity = 0;
}
Your _dynArrSetCapacity function sets up another DynArr block by allocating it again using malloc. The problem here is that you neither return the newData array nor keep the old array (v).
This causes a problem on the caller side. You could've checked your code by doing a while(TRUE) type of block, before exiting _dynArrSetCapacity, which should show that your code doesn't crash before returning.
You have two solutions:
i) Return newData to the caller: While calling _dynArrSetCapacity, your code should update the DynArr variable being used, something like the following:
DynArr *updatedData = _dynArrSetCapacity(newData, newCapacity);
i) Pass a double pointer to _dynArrSetCapacity: The other way is to allow _dynArrSetCapacity to automatically update the pointer to the old DynArr struct. This would require the caller to pass a pointer to that pointer (resulting a double pointer of course). This is called passing out parameters sometimes.
void _dynArrSetCapacity(DynArr** oldData, int newCapacity);
{
DynArr *orgBuffer;// Our new dynamic array to hold the original
// buffer of data
.... Code that will initialize the buffer, do something cool....
_dynArrSetCapacity(&orgBuffer, NEW_CAPACITY);
}
The error you did while coding is that at the end of _dynArrSetCapacity you wrote v = newData and thought that it will be updated for the caller. That is wrong totally. That is because v is copied in the stack and then passed to the callee, which means any changes to v will not affect the originally passed argument (in code).
You don't need to do the realloation yourself, you can use a function called realloc that help you resize an malloc'd array, so the implementation is simpler.
void _dynArrSetCapacity(DynArr *v, int newCap)
{
if(v==NULL||v->data==NULL){
return; // Return early if they are NULL
}
/* Resize the data to newcap*sizeof(TYPE) bytes */
TYPE* tmp=(TYPE*)realloc(v->data,newCap*sizeof(TYPE));
if(tmp!=NULL){
v->data=tmp;
}
}
I would like some help accessing the arrays in my struct. My program compiles without any errors, but stalls when I try to change some values in my struct. I'm stumped as to what the problem is, and would greatly appreciate some assistance.
Global struct declaration:
typedef struct Data {
float timestamp[array_length];
float azimuth[array_length];
float distance[array_length];
float signal_strength[array_length];
} Datain;
Datain *dataptr;
This is were I try to initialize the arrays to what I would like them to be:
for (i = 0; i < array_length; i++)
{
dataptr->timestamp[i]=-100;
dataptr->distance[i]=-100;
dataptr->azimuth[i]=-100;
dataptr->signal_strength[i]=-100;
}
Let me know what you think
dataptr is an uninitialized pointer, it's pointing to nowhere. You have to
allocate memory for it:
dataptr = malloc(sizeof *dataptr); // or malloc(size * sizeof *dataptr)
// for allocating size Datain objects
if(dataptr == NULL)
{
// error handling
// do not continue
}
for(i=0;i<array_length;i++)
{
dataptr->timestamp[i]=-100;
dataptr->distance[i]=-100;
dataptr->azimuth[i]=-100;
dataptr->signal_strength[i]=-100;
}
/*
or if you do the malloc(size * sizeof *dataptr)
for(size_t i = 0; i < size; ++i)
{
for(size_t j = 0; j < array_length; ++j)
{
dataptr[i].timestamp[j]=-100;
dataptr[i].distance[j]=-100;
dataptr[i].azimuth[j]=-100;
dataptr[i].signal_strength[j]=-100;
}
}
*/
and later you don't have to forget to free the memory with
free(dataptr);
And if dataptr is meant to be a single object, then you don't need to declare
it as a pointer:
Datain dataptr; // no * here
then later in a function
for(i=0;i<array_length;i++)
{
dataptr.timestamp[i]=-100;
dataptr.distance[i]=-100;
dataptr.azimuth[i]=-100;
dataptr.signal_strength[i]=-100;
}
and here you don't need to free the memory.
const static int VECTOR_BASIC_LENGTH = 20;
struct m_vector
{
void* my_vector;
size_t my_capacity;
size_t my_head;
};
typedef struct m_vector Vector;
Vector creat_Vector(size_t size,void *judge)
{
Vector _vector;
size = size?size:VECTOR_BASIC_LENGTH;
_vector.my_capacity = size;
_vector.my_head = 0;
//How I write the following two lines
_vector.my_vector = malloc(sizeof(*judge) * size);
return _vector;
}
The type of judge is uncertain,so I pass a void pointer as a parameters.I need the size of *judge to allocate memory to _vector.my_vector,for example if I use:
int *a;
creat_Vector(5,a);
I want the following line:
_vector.my_vector = malloc(sizeof(*judge)*size);
is equal to:
_vector.my_vector = malloc(sizeof(*a)*5);
How could I achieve this function.Using pure C
There is a forbidden thing done in your code.
You statically (at compile time) allocate/declare a local _vector of type Vector in your function creat_Vector. Then you return this object to the outside world. However, when you are exiting your function, all local data is dead. So, you should absolutely rethink this.
One suggestion would be:
int init_Vector(Vector* _vect, size_t size, unsigned int ptr_size)
{
size = size?size:VECTOR_BASIC_LENGTH;
_vect->my_capacity = size;
_vect->my_head = 0;
_vect->my_vector = malloc(size*ptr_size);
if (_vect->my_vector) {
return 0;
}
return 1;
}
Then:
Vector _vector;
char *a;
if (init_Vector(&_vector, 5, sizeof(char)) == 0) {
printf("Success!\n");
}
else {
printf("Failure!\n");
/* treat appropriately (return error code/exit) */
}
/* do whatever with a (if needed) and _vector*/
I have a queue of set length implemented as a dynamic c array implemented like this:
typedef struct {
float* queue;
int size;
int pointer;
} QueueStruct;
void createQueue(QueueStruct* queueInstance, int size){
queueInstance->queue = malloc(sizeof(float)*size);
queueInstance->size = size;
queueInstance->pointer = 0;
}
void addElementToQueue(QueueStruct* queueInstance,float element){
queueInstance->queue[pointer] = element;
if (queueInstance->pointer == queueInstance.size - 1){
queueInstance->pointer = 0;
} else {
++queueInstance->pointer;
}
}
void freeQueue(QueueStruct* queueInstance){
free(queueInstance->queue);
}
And I want to implement this function:
float* returnQueue(QueueStruct queueInstance){
//I want this function to malloc a new float* and then put the queue in it in the
// correct order, from start to finish, as pointed too by the pointer.
//Im not sure how to do this.
}
Any help would be appreciated.
Edit: Corrected a silly programming mistake - this is a simplified version of what is actually in my program.
Let's see if I got that right.
float* returnQueue(QueueStruct *queueInstance){
int j = 0;
float *ret = malloc(sizeof(float)*queueInstance->size); //Allocates the memory you want.
//Copies the elements from pointer to End into the new buffer (assumes, that the array has been filled at least once, add a marker to make sure)
if(queueInstance->FilledOnce) { //Marker variable, explanation as above.
for(int i = queueInstance->pointer; i < queueInstance->size; ++i, ++j)
ret[j] = queueInstance->queue[i];
}
//Copies the newest elements (from beginning to pointer) into the buffer.
for(int i = 0; i < queueInstance->pointer; ++i, ++j)
ret[j] = queueInstance->queue[i];
return ret; //Returns the code in question.
}
To make this code work, you'd have to add 'FilledOnce' to your struct, and amend your 'Add' Code as follows:
void addElementToQueue(QueueStruct* queueInstance, float element){
queueInstance->queue[queueInstance->pointer] = element;
if (queueInstance->pointer == queueInstance.size - 1){
queueInstance->pointer = 0;
queueInstance->FilledOnce = 1;
} else {
++queueInstance->pointer;
}
}
I also advise you, to reset your variables, once you're done with it.
void freeQueue(QueueStruct* queueInstance){
free(queueInstance->queue); //Frees the queue
queueInstance->queue = NULL; //Nulls the reference
queueInstance->FilledOnce = 0;
queueInstance->pointer = 0;
queueInstance->size = 0;
}
This way, if you reuse the struct, you won't run into the problem of trying to access non-allocated memory. Just be sure to check for those variables.
I hope this helps.
I think you should allocate memory for your struct also.
You have made pointer of struct but forgot to allocate memory for that struct
use QueueStruct queuestruct= malloc(sizeof(Queuestruct))
then when you pass this to any of the function above then you can easily allocate
memory for queue poiter in which you can store element for your queue array
This implementation is insufficient. A pointer variable give us location of a tail of queue, but what points to it's head?
I'm having some very strange bug in my ANSI C program.
I'm using debugger and I've observed that 'size' variable is corrupted in function 'doSthing.' Outside of 'doSthing' 'size' got a proper value, but inside 'doSthing' I've got a value nothing similar to what it should be, possibly some random data. This would be not be such a mystery but...
In 'doAnotherThing' which is called from 'doSthing' I get the proper value again. I suppose if it passes the correct value, it is not corrupted anyway, am I wrong? But then why does it have a different value?
The pointer in struct does not change inside the functions.
Memory is allocated for both oTV and oTV->oT.
I really don't see what's happening here...
typedef struct{
ownType *oT[] /* array of pointers */
int size;
} ownTypeVector;
void doSthing(ownTypeVector* oTV);
void doAnotherThing(ownTypeVector* oTV);
void doSthing(ownTypeVector* oTV)
{
...
doAnotherThing(oTV);
...
}
Thanks for your comments, I collected all the code that contains control logic and data structures so that it compiles. It runs on in an embedded systems, that can receive characters from multiple sources, builds strings from it by given rules and after the strings are ready, calls a function that needs that string. This can also be a list of functions. This is why I have function pointers - I can use the same logic for a bunch of things simply by choosing functions outside the 'activityFromCharacters' function.
Here I build a data structre with them by adding A-s, B-s and C-s to the AVector.
Of course every one of these separate sources has their own static strings so that they do not bother each other.
The problem again in the more detailed version of the code:
'aV->size' has got a proper value everywhere, except 'handleCaGivenWay.' Before it gets calles, 'aV->size' is ok, in 'addA' 'aV->size' is ok, too. After leaving 'handleCaGivenWay' it is ok again.
#define NUMBER_OF_AS 1
#define NUMBER_OF_BS 5
#define NUMBER_OF_CS 10
typedef struct{
char name[81];
} C;
typedef struct{
C *c[NUMBER_OF_CS]; /* array of pointers */
int size;
int index;
} B;
typedef struct{
B *b[NUMBER_OF_BS]; /* array of pointers */
char name[81];
int size;
} A;
typedef struct{
A *a[NUMBER_OF_AS]; /* array of pointers */
int size;
} AVector;
typedef struct {
char *string1;
char *string2;
} stringBundle;
typedef struct{
void (*getCharacter)(char *buffer);
void (*doSthingwithC)(stringBundle* strings,AVector* aV);
AVector* aV;
} functionBundle;
void getCharFromaGivenPort(char *buffer)
{
//...
}
void addA(AVector * aV, stringBundle* strings)
{
aV->a[aV->size]->size = 0;
++aV->size;
int i = 0;
if(strlen(strings->string2) < 81)
{
for(i;i<81;++i)
{
aV->a[aV->size-1]->name[i] = strings->string2[i];
}
}
else {report("Too long name for A:");
report(strings->string2);}
}
void handleCaGivenWay(stringBundle* strings,AVector* aV)
{
A* a;
a = NULL;
if(aV->size) { a = aV->a[aV->size-1]; }
switch(1)
{
case 1: addA(aV,strings); break;
case 2: //addB()...
default: if (a && aV->size)
{ //addC(a->thr[a->size-1],c);
}
else report("A or B or C invalid");
break;
}
//handleCaGivenWay
}
void activityFromCharacters(stringBundle* strings,functionBundle* funcbundle)
{
/* some logic making strings from characters by */
/* looking at certain tokens */
(* funcbundle->doSthingwithC)(strings,funcbundle->aV);
}
//activityFromCharacters
AVector* initializeAVector(void)
{
AVector* aV;
if (NULL == (aV = calloc(1,sizeof(AVector))))
{ report("Cannot allocate memory for aVector."); }
int i = 0;
int j = 0;
int k = 0;
for(i; i < NUMBER_OF_AS; ++i)
{
if (NULL == (aV->a[i] = calloc(1,sizeof(A))))
{ report("Cannot allocate memory for As."); }
aV->a[i]->size = 0;
aV->a[i]->name[0] = 0;
for(j; j < NUMBER_OF_BS; ++j)
{
if (NULL == (aV->a[i]->b[j] = calloc(1,sizeof(B))))
{ report("Cannot allocate memory for Bs."); }
aV->a[i]->b[j]->size = 0;
for(k; k < NUMBER_OF_CS; ++k)
{
if (NULL == (aV->a[i]->b[j]->c[k] = calloc(1,sizeof(C))))
{ report("Cannot allocate memory for Cs."); }
}
}
}
aV->size = 0;
return aV;
//initializeProgramVector
}
int main (void)
{
AVector* aV;
aV = initializeAVector();
while(1)
{
static stringBundle string;
static char str1[81];
static char str2[81];
string.string1 = str1;
string.string2 = str2;
functionBundle funcbundle;
funcbundle.getCharacter = &getCharFromaGivenPort;
funcbundle.doSthingwithC = &handleCaGivenWay;
funcbundle.aV = aV;
activityFromCharacters(&string,&funcbundle);
}
//main
}
your code shows that it hasn't any error...
But i think you are doing mistake in getting the value of size in doSthing function.
you are printing there its address. so concentrate on some pointer stuff..
Try printing the oTV->size just before the call and as the first statement in doSthing function. If you get the correct value in both print, then the problem is with the function doSthing. Problem could be better understood if you've shown the code that calls doSthing.
Searched a long time to find this. I found 2 problems, but dont know what exactly you are trying to accomplish so i cannot tell for certain that the fix'es i propose are what you intend.
typedef struct{
A *a[NUMBER_OF_AS]; /* array of pointers */
int size;
} AVector;
// and in addA():
aV->a[aV->size]->size = 0;
First: You are inlining the array of pointers in the struct. What i think what you want and need is a pointer to a pointer array so that it can grow which is what you want in addA() i think. The line from addA() aV->a[aV->size]->size = 0; does not communicate your intention very well but it looks like you are trying to change the value beyond the last entry in the array and since it is inlined in the struct it would result to the separate field size by pure coincidence on some alignments; this is a very fragile way of programming. So what i propose is this. Change the struct to contain A** a; // pointer to pointer-array, malloc it initially and re-malloc (and copy) it whenever you need it to grow (in addA()).