Domanda

Qualche prefazione:Sono uno studente di ingegneria informatica che segue una prima lezione in C dopo 3 semestri di Java (fino a strutture dati).Questa domanda è in relazione a un compito a casa, ma mi mancano alcuni passaggi per risolverlo.

Ho un file di input che leggo in memoria in modo tale che sia archiviato in char[9][500].Ho letto al massimo 500 stringhe di lunghezza massima 8.Sto tentando di ordinare questo array utilizzando la funzione qsort() incorporata di stdlib e riscontro alcuni errori di memoria.

Frammenti di codice importanti:

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

Questa sezione legge i dati negli array.L'array di interesse in questa parte è "debug".Questo è l'array specificato sopra.Ecco la mia funzione di confronto per 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);
}

Questo è il mio tentativo di chiamare 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);

Ho tentato di sostituire debug_len nella mia chiamata dove si trova count, ma sto ancora effettuando il segfault.Ecco l'output:

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

Grazie!

È stato utile?

Soluzione

La funzione di confronto riceverà puntatori agli elementi che vengono confrontati. Stai effettivamente cercando di confrontare i personaggi usando strncmp(). Dato che hai puntatori a ciascuna delle corde, lanciarlo a a char * e confronta.

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

Ricorda anche, è una serie di array, non una serie di suggerimenti. Quindi la dimensione di un elemento dovrebbe avere la dimensione dell'array, 9 e non del puntatore, 4. A questo punto, sarebbe più facile usare sizeof debug[0] poiché è un array bidimensionale. Se non lo fai con le dimensioni giuste, qsort() Distruggerà solo il tuo array.

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);

Altri suggerimenti

Quello che succede qui è:hai 500 corde.Ora passi tutti e 500 a qsort, che a sua volta li passa ciascuno come primo e secondo argomento alla tua funzione di confronto.E' un po' come scrivere questo:

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

Il compilatore C passa gli indirizzi, ovviamente non i valori effettivi.Ma ora interpreti il ​​puntatore a vuoto come puntatore a puntatore a carattere.Il tuo codice ora esegue una dereferenziazione durante la chiamata strncmp, ma questo rende il valore (i primi 4 byte) essere trattati come un puntatore in strncmp.Ma strncmp proverà ora a sua volta a dereferenziare il "puntatore" spazzatura (che consiste in parte di una delle tue stringhe) e questo rende scoppio.

Per risolvere questo problema, utilizzare char * invece di char **:

int compare(const void* a, const void* b)
{
    puts("I'm in compare!");
    return strncmp((const char *)a, (const char *)b, 8);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top