2011-03-20 14 views
7

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í.Usando qsort() de stdlib para ordenar una matriz de cadenas

Tengo un archivo de entrada que leo en la memoria de manera que se almacena en el carácter [9] [500]. Leo 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.

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++; 
} 

En esta sección se 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 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); 

que intentaron sustituir debug_len en mi llamada en cuenta es, pero todavía estoy en violación de segmento. Aquí está la salida:

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

¡Gracias!

+0

while (! Feof()) es incorrecto. feof devolverá false, se ingresará el bucle, el scanf no podrá leer datos, debug [count] contendrá datos falsos, y luego feof devolverá true. Puedes arreglar este caso haciendo count-- después del loop, pero en general simplemente nunca debes hacer while (!feof()) –

+1

¿Dónde se segfault? Es un buen ejercicio examinar el volcado del núcleo para determinar dónde ocurre el segfault, ya que generalmente le dice cuál es el problema. –

Respuesta

8

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 a cada una de las cadenas, cámbielo a 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. Por lo tanto, 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 simplemente usar sizeof debug[0] ya que es una matriz bidimensional. Si no haces esto con los tamaños correctos, qsort() 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); 
3

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 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 al strncmp, pero eso hace que el valor (los primeros 4 bytes) se trate como un puntero en strncmp. Pero strncmp ahora tratará de eliminar la referencia del "puntero" de basura (que consiste en parte de una de sus cadenas) y eso hace bang.

Para corregirlo, use char * en 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); 
} 
+0

s/strncmp/strncmp/ –

+0

@Jim Balter: Gracias, he corregido mi respuesta. – DarkDust

Cuestiones relacionadas