I have been writing a piece of code for my coursework in electromagnetic simulation and I have run into a problem. I decided to do a bit extra by expanding the original calculations to really large meshes of up to 10^8 elements, so now I have to use malloc().
So far, so good, but since I prefer to keep my code in libraries and then compile with the inline option of the compiler, I needed a way to pass information between functions. So, I started using structs to keep track of the parameters of the mesh, as well as the pointer to the array of information. I defined the struct the following way:
typedef struct {
int height;
int width;
int bottom; //position of the bottom node
unsigned int*** dat_ptr;//the pointer to the array with all the data
} array_info;
Where the triple pointer to an unsigned int is the pointer to a 2D array. I have to do it this way because otherwise it is passed by value and I cannot change it from within the function.
Now, when I try to allocate memory for the struct with the following function:
void create_array(array_info A)//the function accepts struct of type "array_info" as argument
{
int i;
unsigned int** array = malloc(sizeof(*array) * A.height);//creates an array of arrays
for(i = 0; i<A.height; ++i)
{
array[i] = malloc(sizeof(**array) * A.width);//creates an array for each row
}
*A.dat_ptr=array;//assigns the position of the array to the input pointer
}
I get a segmentation fault upon executing the operation. I cannot see why: sizeof(*A.dat_ptr) is the same as sizeof(array). Thus, in the worst case I should be getting gibberish somewhere down the line, not in the assignment line, right?
You either need to return the
array_info
structure (as amended) from the function or (more usually) pass a pointer to thearray_info
structure into the function so that the changes you make affect the value in the calling function.I assume you do some checking on the memory allocations somewhere; the logical place is this function, though. Recovery from a failure part way through is fiddly (but necessary if you are going to return from the function rather than exit from the program).
The calling function knows that the function failed if the
dat_ptr
member is null on return fromcreate_array()
. It might be better to provide a success/failure return value.I'm using C99, so the calling code might be:
Note that the code in
create_array()
might need to check for a null pointer, for negative or zero width or height. I'm not clear what thebottom
element should contain, so I left it uninitialized, which gives me half an excuse for using designated initializers. You can also write the initializer quite clearly without using designated initializers.