Reputation: 1139
I've got problems with a pointer to a two dimensional array. The pointer shall point to an array of variable size.
// create pointer to 2 dimensional array
TimeSlot **systemMatrix; // this is a global variable
In a function I want to create a new array.
void setup(uint16_t lines, uint16_t coloumns) {
// create 2 dimensional array. size can be set here.
TimeSlot tmpTimeSlots[lines][coloumns];
// make the pointer point to this array
systemMatrix = tmpTimeSlots; // WARNING
}
But when I let the pointer point to the array the compiler says "warning: assignment from incompatible pointer type". In addition, the mikrocontroller where the software shall run on gets a hard fault when accessing systemmatrix[2][5] from another function.
The variable systemMatrix is needed later when accessing the elements of tmpTimeSlots.
I tried combinations like
systemMatrix = *(*tmpTimeSlot);
and so on but none of them seem to work.
Any help is appreciated :) Thanks!
EDIT: okay problem understood and solved, thanks a lot!
Upvotes: 1
Views: 7261
Reputation: 26204
You are trying to save a pointer to a local object (allocated on stack) and use it after it goes out of scope. This is wrong, the pointer will be invalidated after the function completes.
Also. read answers on this question: Heap allocate a 2D array (not array of pointers) to learn how to allocate a 2 dimensional array dynamically (on the heap, as oppose to stack).
Upvotes: 1
Reputation: 126927
There are several errors here.
TimeSlot **systemMatrix;
This cannot be used to point to a C multidimensional array (as declared later); instead, it can be used to point to a vector of vectors, which is a different beast (have a look at your C book for more details on this). The point is, to point to a multidimensional array you should have a declaration like this:
TimeSlot (* systemMatrix)[lines];
which is a pointer to a vector of length lines
, that can be used to address the multidimensional array (see here for more details). Now, this requires lines
to be known at compile-time, so it isn't appropriate in your case.
And even if your systemMatrix
declaration was correct for the assignment you do in that function, you would be assigning to that pointer the address of memory allocated inside that function, that ceases to exist after the function exit - so your systemMatrix
would become an invalid pointer as soon as setup
returns.
What you need here is dynamic allocation of memory. This allows you to specify an arbitrary lifetime for that memory and to use the double bracket syntax.
First of all, you allocate a vector of pointers, as big as the number of rows you need to have (multiplied by sizeof(int *)
in the call to malloc
); then, you allocate the row vectors and assign each one of them to its place in the column vector. See this answer for more details on this (and other) solutions to allocate dynamically a multidimensional vector.
Don't forget to free
each and every allocated vector when you don't need them anymore!
Upvotes: 2
Reputation: 18368
Your systemMatrix
pointer isn't a pointer to 2D array but a double-dereferencing. You need to declare it like this: TimeSlot (*systemMatrix)[columns];
- this is the correct type for 2D-array pointer. You need, however, the columns
value to be known at the place of the declaration (in C99) or constant (pre-C99).
In addition, returning a pointer to a local variable will result in dangling pointer after the function returns.
Upvotes: 4
Reputation: 72746
Two problems:
TimeSlot **systemMatrix;
does not declare a two dimensional array, but a pointer to a pointer to a Timeslot
. See the comp.lang.c FAQ for how to dynamically create multidimensional arrays.Upvotes: 1
Reputation:
Two-dimensional arrays != double pointers.
You almost certainly need dynamic memory allocation for this. You also want to deep copy the contents of the array - it's a non-static local variable, so it's invalid out of its scope. You can't do TYPE arr[sz]; return arr;
as a consequence.
const size_t width = 3;
const size_t height = 5;
TimeSlot tmpTimeSlot[width][height];
systemMatrix = malloc(width * sizeof systemMatrix[0]);
for (int i = 0; i < width; i++) {
systemMatrix[i] = malloc(height * sizeof systemMatrix[i][0]);
for (int j = 0; j < height; j++) {
systemMatrix[i][j] = tmpTimeSlot[i][j];
}
}
Upvotes: 6