con clase bidimensional array c arrays pointers dynamic-memory-allocation

clase - C: agregar elemento a la matriz asignada dinĂ¡micamente



malloc c con clase (3)

Editado para aclarar un poco más.

El problema es que su rutina de inicio está trabajando con una copia de "vector" y está mallocándose en esa copia en lugar de en el puntero de vector original. Pierdes el puntero al bloque de memoria en el retorno desde la inicialización.

Cambie el parámetro para vector a un manejador (puntero a puntero) en esta función

void initialize_vector( int **vector ) { *vector = (int *)malloc(sizeof(int) * size); }

Luego cambie la llamada a init a este

initialize_vector(&vector);

No compilé esto, pero debería arreglar el código.

Intenté buscar una solución a través de Google: no pude encontrar nada que me ayudara; incluso parecía como si estuviera haciendo esto correctamente. Las únicas páginas que pude encontrar con respecto al envío de mi matriz dinámicamente asignada a través de una función trataban que la matriz estuviera dentro de una estructura, que es escalar, por supuesto, por lo que se comporta de manera diferente. No quiero usar una estructura en este momento. Estoy tratando de aprender sobre DAM y trabajar con punteros y funciones.

Dicho esto, estoy seguro de que es muy elemental, pero estoy atascado. El código se compila, pero se congela cuando ejecuto el ejecutable. (Estoy usando minGW gcc, si eso importa. Y no estoy nada claro, en este momento, sobre cómo usar gdb).

Aquí está el código (eventualmente, quiero que todo el código sea una estructura de datos similar a ArrayList):

#include <stdio.h> #include <stdlib.h> void add( int element, int *vector); void display_vector( int *vector ); void initialize_vector( int *vector ); int elements = 0; int size = 10; int main(void) { int *vector = 0; initialize_vector(vector); add(1, vector); //add(2, vector); //add(3, vector); //add(4, vector); //add(5, vector); //add(6, vector); //add(7, vector); //add(8, vector); //add(9, vector); //add(10, vector); //add(11, vector); display_vector(vector); return 0; } void add( int element, int *vector) { vector[elements++] = element; return; } void display_vector( int *vector ) { int i; for( i = 0; i < elements; i++) { printf("%2d/t", vector[i]); if( (i + 1) % 5 == 0 ) printf("/n"); } printf("/n"); return; } void initialize_vector( int *vector ) { vector = (int *)malloc(sizeof(int) * size); }


En C, los argumentos de las funciones se pasan por valor, lo que significa que hay una copia local para cada argumento que pasas a una función, si cambias un argumento en una función, solo cambias la copia local de ese argumento. Por lo tanto, si desea cambiar el valor de un argumento en una función, debe pasar su dirección a esa función, cancelarla y asignarle el resultado en esa función.

Suficiente para la teoría, aquí está cómo arreglar tu código:

void initialize_vector( int **vector ); initialize_vector(&vector); void initialize_vector( int **vector ) { *vector = (int *)malloc(sizeof(int) * size); }


Además de otras respuestas, sugeriría otro enfoque.

Suponiendo al menos un compilador compatible con C99 , prefiero sugerir que se mantenga el tamaño asignado en un miembro de una estructura que finaliza con un miembro flexible de la matriz (ver también esto ) como:

typedef struct vector_st { unsigned count; // used length unsigned size; // allocated size, always >= length int vectarr[]; } Vector;

Entonces construirías tal vector con

Vector* make_vector (unsigned size) { Vector* v = malloc(sizeof(Vector)+size*sizeof(int)); if (!v) { perror("malloc vector"); exit (EXIT_FAILURE); }; memset (v->vectarr, 0, size*sizeof(int)); v->count = 0; v->size = size; }

Para agregar un elemento a un vector, devolviendo el vector original o uno grande:

Vector* append_vector (Vector*vec, int elem) { assert (vec != NULL); unsigned oldcount = vec->count; if (oldcount < vec->size) { vec->vectarr[vec->count++] = elem; return vec; } else { unsigned newsize = ((4*oldcount/3)|7) + 1; Vector* oldvec = vec; vec = malloc(sizeof(Vector)+newsize*sizeof(int)); if (!vec) { perror("vector grow"); exit(EXIT_FAILURE); }; memcpy (vec->vectarr, oldvec->vectarr, oldcount*sizeof(int)); memset (vec->vectarr + oldcount, 0, (newsize-oldcount) * sizeof(int)); vec->vectarr[oldcount] = elem; vec->count = oldcount+1; vec->size = newsize; free (oldvec); return vec; } }

y podrías codificar:

Vector* myvec = make_vector(100); myvec = append_vector(myvec, 35); myvec = append_vector(myvec, 17); for (int i=0; i<150; i++) myvec = append_vector(myvec, i*2);

Para lanzar un vector así, solo use free(myvec);

Si realmente no desea utilizar ninguna struct , debe mantener en variables separadas la longitud utilizada de su vector, el tamaño asignado de su vector, el puntero a su matriz asignada dinámicamente:

unsigned used_count; // useful "length" unsigned allocated_size; // allocated size, always not less than used_count int *dynamic_array; // the pointer to the dynamically allocated array

Si desea poder administrar varios vectores, empaquete la longitud útil anterior, el tamaño asignado y la matriz dinámica en algún struct dynamic_array_st (cuyo puntero pasaría a las rutinas apropiadas como make_dynamic_vector(struct dynamic_array_st*) , append_dynamic_vector(struct dynamic_array_st*, int) , etc ....) o bien pasarlos como tres formales separados a rutinas similares, y luego tendrá que pasar su dirección porque las rutinas los cambiarían, por ejemplo, create_dynamic_vector(unsigned *countptr, unsigned *sizeptr, int**vectarrptr) que invocarías como create_dynamic_vector(&mycount, &mysize, &myvectarr); etc.

Creo que un miembro de matriz flexible sigue siendo el enfoque más limpio.