Solved

memory allocation in structures

Posted on 2004-04-24
12
516 Views
Last Modified: 2010-04-15
Hello all,
I am experiencing trouble with memory allocation and de-allocation to the following C structure. I might be wrong, but I would like to know the correct procedure to do it.

//globally declared variables
int num_steps = 0;
int num_parts = 0;
struct TIMESTEP
{
float *x;
float *y;
float *z;
};
TIMESTEP *timestep;

//right now, I dont know how many timestep structures I will need and how many x,y & z would be needed in the structure. I would know that info in the run time. Later, in the run time, I would know for example:
num_steps = 10;
num_parts = 25;

//Then, in some function blaw_blaw():


void blaw_blaw(int num_steps, int num_parts)
{
free(timestep->x);
free(timestep->y);
free(timestep->z);
free(timestep);

timestep = (struct TIMESTEP *)malloc(num_steps*sizeof(struct TIMESTEP));
for(int i=0; i<num_steps; i++)
{
timestep[i].x = (float *)malloc(num_steps*sizeof(float));
timestep[i].y = (float *)malloc(num_steps*sizeof(float));
timestep[i].z = (float *)malloc(num_steps*sizeof(float));
}

for(int j=0; j<num_parts; j++)
   {
   for(i=0; i<num_steps; i++)
       {
      fscanf(fp3, "%s%s%s%s%s%s", s1, s2, s3);  //obtained from some ascii file
      timestep[i].x[j] = (float) atof(s1);
      timestep[i].y[j] = (float) atof(s2);
      timestep[i].z[j] = (float) atof(s3);
     }
   }
}
//I call this function at some place in my code. The above scheme of memory allocation and deallocation kind of worked for me once. However, later in my code when I had to re-use the variable with some more memory, the program crashed.


Question: IS THIS A CORRECT SCHEME OF MEMORY ALLOCATION AND DE-ALLOCATION TO C-STRUCTURES OF UNKNOWN NUMBER WITH ITS ARRAY MEMBERS OF UNKNOWN SIZE ? If NO, what is the correct way? I dont have any idea of linked lists, and I am out of time to learn the ABCDs of linked lists. Can some one really explain me how to allocate and de-allocate memory in the above structure ? I also dont know the x, y, z array sizes. Can some one please help me?

Thanks,
Vijay.

0
Comment
Question by:vijaykiran
12 Comments
 
LVL 9

Expert Comment

by:ankuratvb
Comment Utility
For allocation ,you'd do:

timestep = (struct TIMESTEP *)malloc(num_steps*sizeof(struct TIMESTEP));
for(int i=0; i<num_steps; i++)
{
timestep[i].x = (float *)malloc(num_steps*sizeof(float));
timestep[i].y = (float *)malloc(num_steps*sizeof(float));
timestep[i].z = (float *)malloc(num_steps*sizeof(float));
}


For freeing.you'd do:

for(int i=0; i<num_steps; i++)
{
free(timestep[i].x);
free(timestep[i].y);
free(timestep[i].z);
}
free(timestep);

Also,in your function,you are doing:

void blaw_blaw(int num_steps, int num_parts)
{
free(timestep->x);
free(timestep->y);
free(timestep->z);
free(timestep);

In the first execution,you're trying to free memory which hasnt been allocated as yet,which can lead to unexpected results.

So,place the freeing code at the end of the function(or the program as the case may be)
0
 
LVL 23

Assisted Solution

by:brettmjohnson
brettmjohnson earned 100 total points
Comment Utility
You are overrunning your arrays of floats.

Each is allocated to hold num_steps (10) floats, but you populate them with num_parts (25) floats.

Your allocation should look like this:
timestep = (struct TIMESTEP *)malloc(num_steps*sizeof(struct TIMESTEP));
for(int i=0; i<num_steps; i++)
{
      timestep[i].x = (float *)malloc(num_parts*sizeof(float));
      timestep[i].y = (float *)malloc(num_parts*sizeof(float));
      timestep[i].z = (float *)malloc(num_parts*sizeof(float));
}
0
 

Author Comment

by:vijaykiran
Comment Utility
Ohh sorry brettmjohnson,
I did a little mistake while posting the code snippet. I have written my code the way you mentioned though. However, I havent tried the method which ankuratvb suggested. I will check it and get back with results and comments.

Thanks,
vijay.
0
 

Author Comment

by:vijaykiran
Comment Utility
Hello ankuratvb,
I tried using the method you suggested. It still doesnt work for me. In my code, I call the function blaw_blaw a number of times, and I made sure that I free the memory only after I allocate memory atleast once. But even then, it blows up.

I used debug to go in and find out what could be the problem, but it says that it cannot go past the free() at all. I used the header <stdlib.h>
I then used realloc instead of malloc so that I can eliminate free altogether except that I placed free() at the end of the program, which obviously didnt work because I wasnt able to reach the end of the program.

If you guys have any idea what else could  be wrong, please let me know.

Thanks,
Vijay.
0
 
LVL 9

Expert Comment

by:ankuratvb
Comment Utility
Can you post your code?

Also,check the return value of malloc to see whether the mem. was successfully allocated or not.

If you are calling this function a lot of times,i'd suggest using realloc instead of mallocing and freeing every time.
0
 

Assisted Solution

by:agri_amit
agri_amit earned 100 total points
Comment Utility
vijaykiran,

use calloc instead of malloc.and let me know the result.
Also put a error handling after allocating memory like.
if(!timestep )
printf("not able to allocate memory;

it will provide the better pic., what is happ. with ur code.

tx,
amit

0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 

Author Comment

by:vijaykiran
Comment Utility
A dumb question - Is it necessary to free the memory if i reuse a variable by using calloc ? I know that it is not necessary when using realloc. But I am not sure of the case with calloc.

ankuratvb, I am at school right now. I will post the code when I go home. Thank you very much for all the support guys. I really appreciate it. I should have used this site more often.

-vijay.
0
 
LVL 16

Accepted Solution

by:
PaulCaswell earned 200 total points
Comment Utility
vijay,

//globally declared variables
int num_steps = 0; // ** This will just confuse you because you have global and local versions of these variables.
int num_parts = 0; // ** I suggest you remove them.

struct TIMESTEP
{
float *x; // ** Can I guess that there are num_parts of these?
float *y; // ** And these?
float *z; // ** And these?
};
TIMESTEP *timestep; // ** And num_steps of these?

//right now, I dont know how many timestep structures I will need and how many x,y & z would be needed in the structure. I would know that info in the run time. Later, in the run time, I would know for example:
num_steps = 10; // ** Confusing again. See above.
num_parts = 25;

//Then, in some function blaw_blaw():


void blaw_blaw(int num_steps, int num_parts)
{
free(timestep->x);
free(timestep->y);
free(timestep->z);
free(timestep);

// ** This is not the problem!
timestep = (struct TIMESTEP *)malloc(num_steps*sizeof(struct TIMESTEP));
for(int i=0; i<num_steps; i++)
{
timestep[i].x = (float *)malloc(num_steps*sizeof(float)); // ** Change this to num_parts*sizeof(float)
timestep[i].y = (float *)malloc(num_steps*sizeof(float)); // ** And this.
timestep[i].z = (float *)malloc(num_steps*sizeof(float)); // ** And this.
}

for(int j=0; j<num_parts; j++) // ** Change this to i and num_steps
   {
   for(i=0; i<num_steps; i++) // ** Change this to j and num_parts
       {
      // ** You are reading 6 strings into 3 variables, probably a mistake.
      fscanf(fp3, "%s%s%s%s%s%s", s1, s2, s3);  //obtained from some ascii file
      timestep[i].x[j] = (float) atof(s1);
      timestep[i].y[j] = (float) atof(s2);
      timestep[i].z[j] = (float) atof(s3);
     }
   }
}

There are two primary errors that would/will cause crashes.

1. You are allocating the float arrays num_steps long instead of num_parts.
2. You are reading 6 strings into 3 variables. The other 3 strings will go to random locations.

The secondary error, as the others have pointed out, is that you need to deallocate the memory correctly.

Paul
0
 
LVL 9

Assisted Solution

by:ankuratvb
ankuratvb earned 100 total points
Comment Utility
Paul is right.The fscanf() might also be causing the crash(though on my compiler it doesnt crash,i guess it discards the extra parameters read in).

>A dumb question - Is it necessary to free the memory if i reuse a variable by using calloc ? >I know that it is not necessary when using realloc. But I am not sure of the case with >calloc.

Yes.calloc() is also used for allocating memory(not reallocating without free).The difference to malloc is that calloc sets all the allocated memory to zeroed bytes rather than junk values which exist with malloc.

0
 

Author Comment

by:vijaykiran
Comment Utility
I hate this hectic semester. Dont even have time to get some rest. Sorry guys, I've been very bad at responding to the queries/comments.

I am still facing the same problem with my code.

Paul, the code that I posted in my first question was a little changed for understanding sakes. So, I have stripped the un-necessary parts, and while doing so, I have mis-typed a few statements. And yes, I have the correct number of %s's in fscanf statement. Also, I swapped the order of the for loops (i & j). But I still face the same problem.

This function blaw_blaw gets called everytime the file associated with the file pointer fp3 gets changed. That means, I would need to reallocate memory every time the function blaw_blaw gets called. Neither does realloc nor malloc work for me.

The strange thing is that I am having no problems if I do not free the memory at all. If I put the statement free, my program is somehow crashing. When running in Debug mode, it points to the free() function call. I do not have any freaking idea why this is happening.

-vijay.
0
 
LVL 9

Expert Comment

by:ankuratvb
Comment Utility
Why on earth did you close the question then?

You could try this:

In your blaw_blaw function,give only the realloc command,and free the memory when your program is about to end,at the end of main().

What compiler are you using?
Do you have alloc.h or malloc.h included as well?
0
 
LVL 9

Expert Comment

by:ankuratvb
Comment Utility
You could also try the malloc and free() in a separate small program to test whether its your code or the library thats causing the problem.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now