Usando el qsort () de stdlib para ordenar una matriz de cadenas

Algunos prefacio: soy un estudiante de ingeniería informática que toma una primera clase en C después de 3 semestres de Java (hasta estructuras de datos). Esta pregunta está relacionada con una tarea, pero me faltan algunos pasos para resolverla.

Tengo un archivo de entrada que leí en la memoria de manera que está almacenado en char [9] [500]. Leí como máximo 500 cadenas de longitud máxima 8. Estoy intentando ordenar esta matriz utilizando la función qsort () incorporada de stdlib, y tengo algunos errores de memoria.

Fragmentos importantes 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 anteriormente. 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 bash 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 el conteo es, pero todavía estoy segureando. Aquí está la salida:

 $ ./test
 lug de depuración: 1125, recuento: 453, sizeof (char *): 4
 Estoy en comparacion
 Fallo de segmentación (núcleo volcado)

¡Gracias!

La función de comparación recibirá punteros a los elementos que se están comparando. Estás tratando de comparar caracteres utilizando strncmp() . Ya que tiene punteros a cada una de las cadenas, 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); } 

Recuerda también, es una matriz de matrices, no una matriz de punteros. Así que el tamaño de un elemento debe ser el 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 pasa aquí es: tienes 500 cuerdas. Ahora pasa los 500 a qsort y, a su vez, pasa cada uno como primer y segundo argumento a su función de comparación. Es un poco como escribir esto:

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

El comstackdor 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 strncmp referencia al llamar a strncmp , pero eso hace que el valor (los primeros 4 bytes) se trate como un puntero en strncmp . Pero a su strncmp , strncmp intentará desreferenciar el “puntero” de la 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); }