usar multiple libreria keys ejemplo como c arrays string segmentation-fault qsort

multiple - Usar qsort() de stdlib para ordenar una matriz de cadenas



qsort documentation c (2)

Algunos prefacio: soy un estudiante de ingeniería informática tomando una primera clase en C después de 3 semestres de Java (hasta estructuras de datos). Esta pregunta está relacionada con una tarea asignada, pero a pocos pasos de resolverla por mí.

Tengo un archivo de entrada que leí en la memoria de manera que se almacena en el carácter [9] [500]. Leí como máximo 500 cadenas de longitud máxima 8. Estoy intentando ordenar esta matriz usando stdlib''s built en la función qsort (), y estoy teniendo algunos errores de memoria.

Importantes fragmentos de código:

char data[4][500][60]; char debug[500][9]; size_t count = 0; /* initialize file, open for reading */ FILE* pUserlog; pUserlog = fopen("userlog","r"); while(!feof(pUserlog)) { fscanf(pUserlog, "%9s %8s %16s",debug[count], data[1][count], data[2][count]); fgets(data[3][count], 60, pUserlog); count++; }

Esta sección lee los datos en las matrices. El conjunto de intereses en esta parte es "depuración". Esta es la matriz especificada arriba. Aquí está mi función de comparación para qsort:

int compare(const void* a, const void* b) { const char **ia = (const char **)a; const char **ib = (const char **)b; puts("I''m in compare!"); return strncmp(*ia, *ib,8); }

Este es mi intento de llamar a qsort:

size_t debug_len = sizeof(debug)/sizeof(char*); printf("debug len: %d, count: %d, sizeof(char*): %d/n",debug_len,count,sizeof(char*)); qsort(debug,count, sizeof(char *), compare);

Intenté sustituir debug_len en mi llamada donde está el recuento, pero todavía estoy segfaulting. Aquí está el resultado:

$ ./test debug len: 1125, count: 453, sizeof(char*): 4 I''m in compare! Segmentation fault (core dumped)

¡Gracias!


La función de comparación recibirá punteros a los elementos que se están comparando. Está intentando efectivamente comparar personajes usando strncmp() . Como tiene punteros para cada una de las cuerdas, cámbielo a un char * y compare.

int compare(const void* a, const void* b) { const char *ia = (const char *)a; const char *ib = (const char *)b; puts("I''m in compare!"); return strncmp(ia, ib, 9); }

Recuerde también, es una matriz de matrices, no una matriz de punteros. Entonces, el tamaño de un elemento debe ser del tamaño de la matriz, 9 y no del puntero, 4 . En este punto, sería más fácil usar sizeof debug[0] ya que es una matriz bidimensional. Si no haces esto con los tamaños correctos, qsort() simplemente destruirá tu matriz.

size_t elemsize = sizeof debug[0]; /* 9 - size of each element */ size_t count = sizeof(debug)/elemsize; /* 500 - number of elements in array */ qsort(debug, count, elemsize, compare);


Lo que sucede aquí es: tienes 500 cadenas. Ahora pasa los 500 a qsort, y a su vez pasa a cada uno como primer y segundo argumento para su función de comparación. Es un poco como escribir esto:

compare(debug[0], debug[1])

El compilador de C pasa las direcciones, no los valores reales, por supuesto. Pero ahora interpreta el puntero-a-vacío como puntero-a-puntero-a-char. Su código ahora hace una desreferencia al llamar a strncmp , pero eso hace que el valor (los primeros 4 bytes) se trate como un puntero en strncmp . Pero ahora, strncmp intentará eliminar la referencia del "puntero" basura (que consiste en parte de una de sus cadenas) y eso hace que bang .

Para arreglar esto, use char * lugar de char ** :

int compare(const void* a, const void* b) { puts("I''m in compare!"); return strncmp((const char *)a, (const char *)b, 8); }