devuelve la matriz 2d desde la función

Tengo una función que carga datos y los pongo en una matriz

char array_of_string() { char **array; size_t size = 5; size_t index = 0; size_t length = 0; int rd; char *line; array = (char **) malloc(size * sizeof(char*)); while ((rd = getline(&line, &length, 0) != -1) { array[index] = malloc(strlen(line) + 1 * sizeof(char)); strncpy(array[index], line); index++ } free(line); return array; } int main() { char **here; here = array_of_strings(); } 

pero esto no funciona, este es el primer resultado de intentarlo, ¿cómo puedo hacer que funcione?

Como se mencionó en el comentario, tienes varios problemas para corregir. Comenzando con “¿Por qué no funciona getline ?” getline toma un puntero de secuencia FILE * no un descriptor de archivo como su tercer parámetro. Usar stdin lugar de 0 corregirá el problema. Los problemas restantes se ocupan de la asignación. Aquellos han sido discutidos en los comentarios y los ejemplos corregidos se muestran a continuación.

El mayor problema con el que se encontrará es: “¿Cómo sabré cuántas líneas se leyeron realmente?” Tiene un ‘5’ codificado, pero ¿y si lee menos de 5 ?

Para responder a la pregunta, necesita, como mínimo, pasar un puntero como parámetro a su función array_of_string , y actualizar su valor con el valor del index para que el número de líneas leídas esté disponible en la función de llamada ( main() en este caso). De esa manera, siempre se sabe la cantidad de líneas leídas. Por ejemplo:

 char **array_of_string (size_t *n) { ... free (line); *n = index; /* update n with index, so available in main() */ return array; } 

Su próximo desafío es “¿Cómo verifico para asegurarme de no leer y tratar de almacenar más de 5 líneas?” Luego, “¿Qué hago si tengo más de 5 líneas para leer?”, “¿Entonces qué?”. Ahí es donde puede break de su ciclo de lectura o, mejor, usar la función realloc para reasignar la array para boost el número de punteros disponibles. (Puede agregar tantos como desee, pero un enfoque estándar es duplicar el número actual de punteros que tiene; ese enfoque se muestra a continuación).

 #define MAXLN 5 ... char **array_of_string (size_t *n) { ... size_t maxln = MAXLN; ... while ((rd = getline(&line, &length, stdin)) != -1) { ... array[index++] = strdup(line); /* alloc & copy */ if (index == maxln) { /* check limit reached - reallocate */ char **tmp = realloc (array, maxln * sizeof *array * 2); if (!tmp) { fprintf (stderr, "error: realloc - memory exhausted.\n"); *n = index; return array; } array = tmp; /* set new pointers to NULL */ memset (array + maxln, 0, maxln * sizeof *array); maxln *= 2; } } ... } 

Al juntar todas las piezas, podría hacer algo como lo siguiente, que inicialmente asigna un número razonable de punteros para contener la cantidad de líneas que espera leer. Si alcanza ese límite antes de que realloc su lectura, simplemente realloc el número de punteros a 2X de stream. (si realloc una realloc puntero tmp para protegerse contra la pérdida de todos los datos existentes en la array si falla la realloc . Si realloc tiene éxito, simplemente asigne la array = tmp; )

Eche un vistazo a lo siguiente y avíseme si tiene alguna pregunta al respecto:

 #include  #include  #include  #define MAXLN 5 char **array_of_string (size_t *n); int main (void) { char **here = NULL; size_t i, lines = 0; /* assign array_of_string to here, check return */ if (!(here = array_of_string (&lines))) { fprintf (stderr, "error: array_of_string return NULL.\n"); return 1; } for (i = 0; i < lines; i++) /* print lines */ printf (" line[%3zu] : %s\n", i, here[i]); for (i = 0; i < lines; i++) /* free lines */ if (here[i]) free (here[i]); free (here); /* free here */ return 0; } char **array_of_string (size_t *n) { char **array = NULL; char *line = NULL; size_t index = 0, length = 0, maxln = MAXLN; ssize_t rd = 0; if (!(array = calloc (MAXLN, sizeof *array))) { fprintf (stderr, "error: virtual memory exhausted.\n"); return NULL; } while ((rd = getline(&line, &length, stdin)) != -1) { while (rd > 0 && (line[rd-1] == '\r' || line[rd-1] == '\n')) line[--rd] = 0; /* strip carriage return or newline */ array[index++] = strdup(line); /* alloc & copy */ if (index == maxln) { /* check limit reached - reallocate */ char **tmp = realloc (array, maxln * sizeof *array * 2); if (!tmp) { fprintf (stderr, "error: realloc - memory exhausted.\n"); *n = index; return array; } array = tmp; /* set new pointers to NULL */ memset (array + maxln, 0, maxln * sizeof *array); maxln *= 2; } } free(line); /* free memory allocated by getline */ *n = index; /* update n with index, so available in main() */ return array; } 

Comstackr – con advertencias habilitadas

 gcc -Wall -Wextra -o bin/stdintst stdintst.c 

(o usando opciones similares para tu comstackdor)

Fichero de entrada

 cat ../dat/damages.txt Personal injury damage awards are unliquidated and are not capable of certain measurement; thus, the jury has broad discretion in assessing the amount of damages in a personal injury case. Yet, at the same time, a factual sufficiency review insures that the evidence supports the jury's award; and, although difficult, the law requires appellate courts to conduct factual sufficiency reviews on damage awards in personal injury cases. Thus, while a jury has latitude in assessing intangible damages in personal injury cases, a jury's damage award does not escape the scrutiny of appellate review. Because Texas law applies no physical manifestation rule to restrict wrongful death recoveries, a trial court in a death case is prudent when it chooses to submit the issues of mental anguish and loss of society and companionship. While there is a presumption of mental anguish for the wrongful death beneficiary, the Texas Supreme Court has not indicated that reviewing courts should presume that the mental anguish is sufficient to support a large award. Testimony that proves the beneficiary suffered severe mental anguish or severe grief should be a significant and sometimes determining factor in a factual sufficiency analysis of large non-pecuniary damage awards. 

Uso / Salida

 $ ./bin/stdintst <../dat/damages.txt line[ 0] : Personal injury damage awards are unliquidated line[ 1] : and are not capable of certain measurement; thus, the line[ 2] : jury has broad discretion in assessing the amount of line[ 3] : damages in a personal injury case. Yet, at the same line[ 4] : time, a factual sufficiency review insures that the line[ 5] : evidence supports the jury's award; and, although line[ 6] : difficult, the law requires appellate courts to conduct line[ 7] : factual sufficiency reviews on damage awards in line[ 8] : personal injury cases. Thus, while a jury has latitude in line[ 9] : assessing intangible damages in personal injury cases, line[ 10] : a jury's damage award does not escape the scrutiny of line[ 11] : appellate review. line[ 12] : line[ 13] : Because Texas law applies no physical manifestation line[ 14] : rule to restrict wrongful death recoveries, a line[ 15] : trial court in a death case is prudent when it chooses line[ 16] : to submit the issues of mental anguish and loss of line[ 17] : society and companionship. While there is a line[ 18] : presumption of mental anguish for the wrongful death line[ 19] : beneficiary, the Texas Supreme Court has not indicated line[ 20] : that reviewing courts should presume that the mental line[ 21] : anguish is sufficient to support a large award. Testimony line[ 22] : that proves the beneficiary suffered severe mental line[ 23] : anguish or severe grief should be a significant and line[ 24] : sometimes determining factor in a factual sufficiency line[ 25] : analysis of large non-pecuniary damage awards. 

Comprobación de errores de memoria

En cualquier código que escriba que asigna memoria dinámicamente, tiene 2 responsabilidades con respecto a cualquier bloque de memoria asignado: (1) siempre conserva un puntero a la dirección de inicio para el bloque de memoria, (2) se puede liberar cuando no está ya se necesita

Es imperativo que use un progtwig de comprobación de errores de memoria para asegurarse de que no ha escrito más allá / fuera del bloque de memoria asignado, intentó leer o basar un salto en un valor no inicializado y finalmente confirmar que ha liberado toda la memoria que ha liberado. han asignado

Para Linux valgrind es la elección normal. Hay muchas formas sutiles de hacer mal uso de un nuevo bloque de memoria. El uso de un verificador de errores de memoria le permite identificar cualquier problema y validar el uso adecuado de la memoria que asigna en lugar de descubrir que existe un problema a través de un segfault . Hay comprobadores de memoria similares para cada plataforma. Todos son fáciles de usar, simplemente ejecute su progtwig a través de él.

 $ valgrind ./bin/stdintst <../dat/damages.txt ==12233== Memcheck, a memory error detector ==12233== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. ==12233== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==12233== Command: ./bin/stdintst ==12233== line[ 0] : Personal injury damage awards are unliquidated line[ 1] : and are not capable of certain measurement; thus, the  line[ 24] : sometimes determining factor in a factual sufficiency line[ 25] : analysis of large non-pecuniary damage awards. ==12233== ==12233== HEAP SUMMARY: ==12233== in use at exit: 0 bytes in 0 blocks ==12233== total heap usage: 31 allocs, 31 frees, 1,989 bytes allocated ==12233== ==12233== All heap blocks were freed -- no leaks are possible ==12233== ==12233== For counts of detected and suppressed errors, rerun with: -v ==12233== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) 

Confirmar siempre Se liberaron todos los bloques de almacenamiento dynamic: no hay fugas posibles e igualmente importante RESUMEN DE ERRORES: 0 errores de 0 contextos .

Déjame saber si tienes más preguntas.

Si va a mantener array_of_string fuera de su función principal (lo que es una buena idea), debe pasar un puntero a la matriz para poder editar directamente el contenido de la misma. Si declara o asigna memoria en un scope, se desasignará automáticamente una vez que finalice el scope. Si luego intentas acceder a esa memoria, obtienes resultados indefinidos. Pase la matriz para funcionar en C

También:

 while ((rd = getline(&line, &length, 0) != -1) { array[index] = malloc(strlen(line) + 1 * sizeof(char)); 

Getline modificará la longitud para que sea el tamaño de la cadena que se asignó. Puede eliminar strlen (línea) y reemplazarlo con la longitud, o con rd para guardar algunos ciclos de CPU. Tenga en cuenta que es posible que rd y length sean diferentes. Getline (3)