sirven que punteros puntero parametros para operaciones memoria los funciones ejemplo dev con como cadenas asignar apuntadores c pointers memory-management matrix

que - matriz int con punteros en confusión de asignación de memoria C



punteros c++ (7)

Tengo algunos problemas para producir una matriz int sin crear pérdidas de memoria. Quiero poder hacer una matriz dada (global) en cualquier tamaño dinámicamente a través de read_matrix (). Pero luego quiero poder liberar la memoria más adelante. Por lo tanto, en mi método principal, la segunda impresión debería dar como resultado un error de bus ya que no debería tener ninguna memoria asignada. ¿Cómo podría crear esto?

int** first_matrix; int** second_matrix; int** result_matrix; int** read_matrix(int size_x, int size_y) { int** matrix; matrix = calloc(size_x, sizeof(int*)); for(int i = 0;i<size_x;i++) { matrix[i] = calloc(size_y, sizeof(int)); } for(int i = 0;i<size_x;i++) { for(int j = 0;j<size_y;j++) { matrix[i][j] = i*10+j; } } return matrix; } int main(int stackc, char** stack) { first_matrix = read_matrix(10,10); printf("9:3 %d - 4:6 %d /n", first_matrix[9][3], first_matrix[4][6]); free(*first_matrix); free(first_matrix); printf("9:3 %d - 4:6 %d /n", first_matrix[9][3], first_matrix[4][6]); }


¡Solo porque la memoria haya sido liberada no significa que no puedas acceder! Por supuesto, es una muy mala idea acceder después de que ha sido liberado, pero es por eso que funciona en tu ejemplo.

Tenga en cuenta que free( *first_matrix ) solo first_matrix[0] libre, no las otras matrices. Es probable que desee algún tipo de marcador para indicar el último conjunto (a menos que siempre sepa cuándo libera el conjunto externo cuántas matrices internas asignó). Algo como:

int** read_matrix(int size_x, int size_y) { int** matrix; matrix = calloc(size_x, 1+sizeof(int*)); // alloc one extra ptr for(int i = 0;i<size_x;i++) { matrix[i] = calloc(size_y, sizeof(int)); } matrix[size_x] = NULL; // set the extra ptr to NULL for(int i = 0;i<size_x;i++) { for(int j = 0;j<size_y;j++) { matrix[i][j] = i*10+j; } } return matrix; }

Luego, cuando los liberes:

// keep looping until you find the NULL one for( int i=0; first_matrix[i] != NULL; i++ ) { free( first_matrix[i] ); } free( first_matrix );


Debe liberar cada fila individualmente:

void free_matrix(int **matrix, int size_x) { for(int i = 0; i < size_x; i++) free(matrix[i]); free(matrix); }


El concepto que te falta aquí, es que para cada calloc, debe haber un gratis. y ese libre se debe aplicar al puntero pasado de calloc.

Te recomiendo que crees una función (llamada delete_matrix) que utiliza un bucle para liberar todos los punteros que asignas aquí

for (int i = 0; i <size_x; i ++) {matrix [i] = calloc (size_y, sizeof (int)); }

luego, una vez hecho esto, libere el puntero asignado por este.

matrix = calloc (size_x, sizeof (int *));

La forma en que lo haces ahora,

gratis (* first_matrix); libre (first_matrix);

no hará lo que quieras que haga.


Liberar la memoria no la hace desaparecer, solo significa que otra asignación podría atrapar ese mismo pedazo de memoria. Lo que sea que pongas, seguirá ahí hasta que algo más lo sobrescriba.

Además, no estás liberando todo lo que asignaste. Solo está liberando la matriz de punteros y la primera fila. Pero incluso si liberas todo correctamente, aún tendrías el mismo efecto.

Si desea crear un "error de bus", debe señalar a la memoria que no pertenece a su proceso. ¿Por qué quieres hacer eso de todos modos?


Obtendrá pérdidas de memoria porque está liberando la primera fila de la matriz y la lista de filas, pero ninguna de las filas 1 a n. Debe llamar gratis en un bucle.

Sin embargo, hay un par de alternativas: - Asignar sizeof (int *) rows + rows cols * sizeof (int) bytes y usar los primeros bytes para los punteros de fila. De esta forma, solo tiene un trozo de memoria libre (y también es más fácil para el asignador): use una estructura que contenga el número de filas. Entonces puede evitar la lista de filas por completo (guardando memoria). El único inconveniente es que debe usar una función, una macro o alguna notación desordenada para abordar la matriz.

Si elige la segunda opción, puede usar una estructura como esta en cualquier compilador C99, y nuevamente solo tiene que asignar un solo bloque de memoria (de tamaño numints * sizeof (int) + sizeof (int)):

struct matrix { int rows; int data[0]; }


Recomiendo usar valgrind para rastrear la memoria no liberada, en lugar de tratar de hacer que ocurra un error de bus. También es bueno para muchas otras cosas.

Sam


Solo liberaste la primera fila (o columna) de first_matrix. Escribe otra función como esta:

void free_matrix(int **matrix, int rows) { int i; for(i=0; i<rows; i++) { free(matrix[i]); } free(matrix); }

Es posible que desee convertir la matriz en una estructura para almacenar su recuento de filas y columnas.