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.
Related
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)
I have a dynamic 2d array inside this struct:
struct mystruct{
int mySize;
int **networkRep;
};
In my code block I use it as follows:
struct myStruct astruct[100];
astruct[0].networkRep = declareMatrix(astruct[0].networkRep, 200, 200);
// do stuff...
int i;
for(i=0; i<100; i++)
freeMatrix(astruct[i].networkRep, 200);
This is how I declare the 2d array:
int** declareMatrix(int **mymatrix, int rows, int columns)
{
mymatrix = (int**) malloc(rows*sizeof(int*));
if (mymatrix==NULL)
printf("Error allocating memory!\n");
int i,j;
for (i = 0; i < rows; i++)
mymatrix[i] = (int*) malloc(columns*sizeof(int));
for(i=0; i<rows; i++){
for(j=0; j<columns; j++){
mymatrix[i][j] = 0;
}
}
return mymatrix;
}
And this is how I free the 2d array:
void freeMatrix(int **matrix, int rows)
{
int i;
for (i = 0; i < rows; i++){
free(matrix[i]);
}
free(matrix);
matrix = NULL;
}
The strange behvior that I'm seeing is that when I compile and run my program everything looks OK. But when I pipe the stdout to a txt file, I'm getting a seg fault. However, the seg fault doesn't occur if I comment out the loop containing the "freeMatrix" call. What am I doing wrong?
I don't see any problem in free code, except, freeMatrix get called for 100 times whereas your allocation is just 1.
So, either you allocate as below:
for(int i=0; i<100; i++) //Notice looping over 100 elements.
astruct[i].networkRep = declareMatrix(astruct[i].networkRep, 200, 200);
Or, free for only 0th element which you have allocated in your original code.
freeMatrix(astruct[0].networkRep, 200);
On sidenote: Initialize your astruct array.
mystruct astruct[100] = {};
struct myStruct astruct[100];
astruct[0].networkRep = declareMatrix(astruct[0].networkRep, 200, 200);
// do stuff...
int i;
for(i=0; i<100; i++)
freeMatrix(astruct[i].networkRep, 200);
You allocated one astruct but free 100 of them; that will crash if any of the 99 extra ones isn't NULL, which probably happens when you do your redirection. (Since astruct is on the stack, it will contain whatever was left there.)
Other issues:
You're using numeric literals rather than manifest constants ... define NUMROWS and NUMCOLS and use them consistently.
Get rid of the first parameter to declareMatrix ... you pass a value but never use it.
In freeMatrix,
matrix = NULL;
does nothing. With optimization turned on, the compiler won't even generate any code.
if (mymatrix==NULL)
printf("Error allocating memory!\n");
You should exit(1) upon error, otherwise your program will crash and you may not even see the error message because a) stdout is buffered and b) you're redirecting it to a file. Which is also a reason to write error messages to stderr, not stdout.
astruct[0].networkRep = declareMatrix(astruct[0].networkRep, 200, 200);
your not passing the address of the pointer. It just passes the value in the memory to the function which is unncessary.
And your only initializing first variable of struct but while you are trying to free the memory you are unallocating memory which is not yet allocated (astruct[1] and so on till 100 ).
When you use a malloc , it actually allocates a bit more memory than you you specified. extra memory is used to store information such as the size of block, and a link to the next free/used block and sometimes some guard data that helps the system to detect if you write past the end of your allocated block.
If you pass in a different address, it will access memory that contains garbage, and hence its behaviour is undefined (but most frequently will result in a crash)
To index and count an unsigned integer type is enough. size_tis the type of choice for this as it is guaranteed to be larger enough to address/index every byte of memory/array's element on the target machine.
struct mystruct
{
size_t mySize;
int ** networkRep;
};
Always properly initialise variables:
struct myStruct astruct[100] = {0};
Several issues with the allocator:
Give it a chance to returned specific error codes. This typically is done by setting using the function returned value to to so.
Use size_t for counters and indicies and sizes ("rows", "columns")(for why please see above).
Do proper error checking.
Clean up in case an error occurs during work.
do not cast the value returned by malloc(), as in C it's not necessary, not recommended
Use perror() to log error, as it gets the most from the OS about the as possibe.
A possible to do this:
int declareMatrix(int *** pmymatrix, size_t rows, size_t columns)
{
int result = 0; /* Be optimistc. */
assert(NULL != pmatrix);
*pmymatrix = malloc(rows * sizeof(**pmymatrix));
if (NULL == *pmymatrix)
{
perror("malloc() failed");
result = -1;
goto lblExit;
}
{
size_t i, j;
for (i = 0; i < rows; i++)
{
(*pmymatrix)[i] = malloc(columns * sizeof(***pmymatrix));
if (NULL == (*pmymatrix)[i])
{
perror("malloc() failed");
freeMatrix(pmymatrix); /* Clean up. */
result = -1;
goto lblExit;
}
for(i = 0; i < rows; ++i)
{
for(j = 0; j < columns; ++j)
{
(*pmymatrix)[i][j] = 0;
}
}
}
}
lblExit:
return 0;
}
Two issues for the de-allocator:
Mark it's work as done be properly de-initilaising the pointer.
Perform validation of input prior to acting on it.
A possible to do this:
void freeMatrix(int *** pmatrix, size_t rows)
{
if (NULL != pmatrix)
{
if (NULL != *pmatrix)
{
size_t i;
for (i = 0; i < rows; ++i)
{
free((*pmatrix)[i]);
}
}
free(*pmatrix);
*pmatrix = NULL;
}
}
Then use the stuff like this:
struct myStruct astruct[100] = {0};
...
int result = declareMatrix(&astruct[0].networkRep, 200, 200);
if (0 != result)
{
fprintf("declareMatrix() failed.\n");
}
else
{
// Note: Arriving here has only the 1st element of astruct initialised! */
// do stuff...
}
{
size_t i;
for(i = 0; i < 100; ++i)
{
freeMatrix(&astruct[i].networkRep, 200);
}
}
UPDATE:
I've changed the static array for a dynamic, but I still get the segment violation error, although eclipse says:
*** glibc detected *** (path to file) double free or corruption (!prev): 0x00000000004093d0 ***
StructHashTable is a typedef...
int main() {
...
StructHashTable *B0 = (StructHashTable *) malloc(N_ELEMS*sizeof(StructHashTable));
...
}
void resizeHash(StructHashTable *hash) {
int size = currentElements + N_ELEMS;
StructHashTable newHash[size];
int i;
for (i = 0; i < size; i++) newHash[i].key = FREE;
for (i = 0; i < currentElements; i++) insertHash(newHash, hash[i]);
currentElements = size;
hash = (StructHashTable *) realloc(hash, size*sizeof(StructHashTable));
if (hash != NULL) {
for (i = 0; i < size; i++) hash[i] = newHash[i];
}
}
What's wrong now? Am I using in a bad way realloc? or what? C is driving me crazy...
OLD:
I'm working in university homework and I need to resize an static array in C, it has to be static, the debbugger says segment violation...
I have a main function that declares the array...
// File: main.c
int main() {
...
StructHashTable hash[N_ELEMS];
...
}
At some point on runtime I need more elements than N_ELEMS and I've written a function to do it in HashTable.c, that's the method:
// File: HashTable.c
#define N_ELEMS 32
int currentElements = N_ELEMS
void resizeHashTable(StructHashTable *hash) {
int size = currentElements + N_ELEMS;
StructHashTable newHash[size];
int i;
// Inicialize newHash
for (i = 0; i < size; i++) newHash[i].key = FREE;
// Insert old hash elements to the new table...
for (i = 0; i < currentElements; i++) {
insertHash(newHash, hash[i]);
}
currentElements = size;
// I've tried making hash null with no luck...
//hash = NULL;
//free(hash);
// HERE'S THE ERROR...
hash = newHash;
// I've tried *hash = *newHash with the same result...
}
Can someone tell me how to do what I'm trying to do?
Thanks.
You are getting error because you are trying to modify the l-value for a statically allocated array 'hash'.
Whenever you define an array (as in main)
StructHashTable hash[N_ELEMS];
sizeof(StructHashTable)*N_ELEMS bytes of memory is allocated for hash, and hash points to the first byte. Such an allocation is called static allocation and you cannot make hash point to some other memory allocation. It will give error as you specified, because the l-value i.e left hand side value cannot be modified. Neither you can free the memory assigned to hash. Memory assigned to hash will be freed only when main will terminate.
// HERE'S THE ERROR...
hash = newHash;
I suggest you to use dynamic memory allocation for hash in main, if you wish to resize hash during run time.
int main() {
...
//Initial hash table creation
StructHashTable *B0 = (StructHashTable *) malloc(N_ELEMS*sizeof(StructHashTable));
...
...
//Do something
...
...
//hash table full. So resize hash table. This function call need not be inside main. Just for illustration purpose I am doing it here.
B0 = resizeHash(B0);
...
}
And here's your modified resizeHash function.
StructHashTable* resizeHash(StructHashTable *oldHash) {
int size = currentElements + N_ELEMS;
int i;
//Allocate memory for newHash with larger number of elements.
StructHashTable *newHash = (StructHashTable*) malloc(size * sizeof(StructHashTable));
if (newHash != NULL) {
for (i = 0; i < currentElements; i++) {
// Copy one by one oldHash table elements into newhash table
//Something like below, or whatever you have been doing before to copy.
newHash[i] = oldHash[i];
}
}
//Free memory occupied by oldHash
free(oldHash);
//Set new value for currentElements
currentElements = size;
//return the newHash address to calling function.
return (newHash);
}
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 am using the CvPoint2D32f struct of opencv, which is defined as
typedef struct CvPoint2D32f
{
float x; /* x-coordinate, usually zero-based */
float y; /* y-coordinate, usually zero-based */
}
CvPoint2D32f;
I am trying to allocate an array of pointers of these objects as follows, and it is not working. How is this to be accomplished?
CvPoint2D32f *cvpoints[8];
for (i = 0; i < 16; i++)
{
if (i % 2 == 0)
{
(*cvpoints)[i/2].x = float(points[i]); // points is an array of ints.
}
else
{
(*cvpoints)[i/2].y = float(points[i]);
}
}
You have an array of pointers to CvPoint2D32f, not an array of the structs themselves. You have no memory allocated for the actual structures. You have three options:
Change your declaration to CvPoint2D32f cvpoints[8]; so you have all of the structures in an array on the stack.
After you allocate the array for the pointers, add a malloc statement to allocate memory. Example:
CvPoint2D32f *cvpoints[8];
for (i = 0; i < 8; i++)
{
cvpoints[i] = (CvPoint2D32f *)malloc(sizeof(CvPoint2D32f));
}
Use malloc to allocate size for all the structures. Example:
CvPoint2D32f *cvpoints = (CvPoint2D32f *)malloc( 8 * sizeof(CvPoint2D32f));
CvPoint2D32f *cvpoints = (CvPoint2D32f*) malloc(sizeof(struct CvPoint2D32f) * 8);
memset(cvpoints, \0, sizeof(struct CvPoint2D32f) * 8);
for (i = 0; i < 16; i++)
{
if (i % 2 == 0)
{
cvpoints[i/2].x = float(points[i]); // points is an array of ints.
}
else
{
cvpoints[i/2].y = float(points[i]);
}
}
And when you're done with them, you free the memory:
free(cvpoints);
Where do these pointers point to? I guess what you want to do is allocate dynamic memory for the structs, but I don't see any memory allocation in your code. Currently all pointers point to undefined memory, so of course this will fail.
You are just creating the pointers, but you need them to point to something in memory!
Example:
struct CvPoint2D32f *cvpoint = (struct CvPoint2D32f *)malloc(sizeof(struct CvPoint2D32f));
if (cvpoint == NULL) {
//malloc error
}