Puntero C a matriz bidimensional

Tengo problemas con un puntero a una matriz bidimensional. El puntero apuntará a una matriz de tamaño variable.

// create pointer to 2 dimensional array TimeSlot **systemMatrix; // this is a global variable 

En una función quiero crear una nueva matriz.

 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 } 

Pero cuando dejo que el puntero apunte a la matriz, el comstackdor dice “advertencia: asignación desde un tipo de puntero incompatible”. Además, el mikrocontroller en el que se ejecutará el software tiene un fallo grave al acceder a la matriz del sistema [2] [5] desde otra función.

La variable systemMatrix se necesita más adelante al acceder a los elementos de tmpTimeSlots.

Probé combinaciones como

 systemMatrix = *(*tmpTimeSlot); 

Y así sucesivamente, pero ninguno de ellos parece funcionar.

Cualquier ayuda es apreciada 🙂 Gracias!

EDIT: bien problema entendido y resuelto, muchas gracias!

Arreglos bidimensionales! = Punteros dobles.

Es casi seguro que necesita asignación de memoria dinámica para esto. También desea copiar en profundidad el contenido de la matriz: es una variable local no estática, por lo que no es válida fuera de su scope. No puedes hacer TYPE arr[sz]; return arr; TYPE arr[sz]; return arr; Como consecuencia.

 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]; } } 

El puntero de la matriz del systemMatrix no es un puntero a la matriz 2D sino una doble referencia. TimeSlot (*systemMatrix)[columns]; declararlo así: TimeSlot (*systemMatrix)[columns]; – Este es el tipo correcto para el puntero de matriz 2D. Sin embargo, necesita conocer el valor de las columns en el lugar de la statement (en C99) o constante (pre-C99).

Además, devolver un puntero a una variable local dará como resultado un puntero colgante después de que la función regrese.

Hay varios errores aquí.

  TimeSlot **systemMatrix; 

Esto no se puede usar para apuntar a una matriz multidimensional C (como se declara más adelante); en su lugar, se puede usar para señalar un vector de vectores, que es una bestia diferente (mire su libro C para más detalles sobre esto). El punto es que, para apuntar a una matriz multidimensional, debe tener una statement como esta:

  TimeSlot (* systemMatrix)[lines]; 

que es un puntero a un vector de lines de longitud, que se puede usar para abordar la matriz multidimensional (consulte aquí para obtener más detalles). Ahora, esto requiere que las lines se conozcan en tiempo de comstackción, por lo que no es apropiado en su caso.

E incluso si su statement systemMatrix fuera correcta para la asignación que realiza en esa función, estaría asignando a ese puntero la dirección de memoria asignada dentro de esa función, que deja de existir después de que la función salga, por lo que su systemMatrix se convertiría en un puntero no válido tan pronto como vuelva la setup .

Lo que necesitas aquí es la asignación dinámica de memoria. Esto le permite especificar un tiempo de vida arbitrario para esa memoria y usar la syntax de doble corchete.

En primer lugar, asigna un vector de punteros, tan grande como el número de filas que necesita tener (multiplicado por sizeof(int *) en la llamada a malloc ); luego, asigna los vectores de fila y asigna cada uno de ellos a su lugar en el vector de columna. Vea esta respuesta para obtener más detalles sobre esta (y otras) soluciones para asignar dinámicamente un vector multidimensional.

¡No olvides free cada vector asignado cuando ya no los necesites!

Dos problemas:

  1. No debe devolver un puntero al almacenamiento automático. Ese almacenamiento queda fuera del scope una vez que se deja la función. Deberías usar malloc () en su lugar. Es probable que el uso de un almacenamiento fuera del scope tenga acceso a la basura en la stack, lo que probablemente cause la falla. Técnicamente esto se llama comportamiento indefinido en C.
  2. Contrariamente a su statement, TimeSlot **systemMatrix; no declara una matriz bidimensional, sino un puntero a un puntero a un Timeslot . Consulte las preguntas frecuentes comp.lang.c para ver cómo crear dinámicamente matrices multidimensionales.

Está intentando guardar un puntero a un objeto local (asignado en la stack) y utilizarlo después de que esté fuera del scope. Esto es incorrecto, el puntero se invalidará una vez que se complete la función.

También. lea las respuestas a esta pregunta: el montón asigna una matriz 2D (no un conjunto de punteros) para aprender cómo asignar una matriz bidimensional dinámicamente (en el montón, como oposición a la stack).