Ich habe eine Datei mit Format: [Name] [Nummer] [Anzahl] Nummer wird als Zeichenfolge genommen. und ich benutze es in einem strcmp. Problem ist, dass ich einen Segmentierungsfehler bekomme. Ich weiß, dass in den meisten Fällen, wenn strcmp einen Segmentierungsfehler meldet, dies bedeutet, dass einer der Parameter null ist oder sein "Ende" ('\ 0') nicht finden kann. Ich habe mit GDB und ich kann nicht sagen, ob dies die problem.Take ist ein Blick:Segmentierung. strcmp [C]
> (gdb) bt full
> #0 0x08048729 in lookup (hashtable=0x804b008, hashval=27,
> number=0x804b740 "6900101001")
> list = 0xffffffff
> #1 0x080487ac in add (hashtable=0x804b008,
> number=0x804b740 "9900101001", name=0x804b730 "Smithpolow",
> time=6943)
> new_elem = 0xffffffff
> hashval = 27
> #2 0x08048b25 in main (argc=1, argv=0xbffff4b4)
> number = 0x804b740 "9900101001"
> name = 0x804b730 "Smithpolow"
> time = 6943
> i = 2
Code:
typedef struct HashTable
{
int length;
struct List *head;
} HashTable;
//(resolving collisions using chaining)
typedef struct List
{
char *number;
char *name;
int time;
struct List *next;
} List;
int primes[]={17,29,51,79,163,331,673,1361,2729,5471,10949,21911,43853,87719,175447,350899};
*int PrimesIndex=1;* **int PrimesIndex=0;** **//changed.**
HashTable *createHashTable(size)
{
HashTable *new_table = malloc(sizeof(*new_table)*size);
if (new_table == NULL)
{ return NULL;
}
int i=0;
for(i; i<size; i++)
{ new_table[i].length=0;
new_table[i].head=NULL;
}
return new_table;
}
int hash (HashTable *hashtable,char* number)
{
int hashval = 0;
int i = 0;
for (i = 0; i < 10; i++)
{ hashval = (hashval << 5)|(hashval >> 27);
hashval += (int)number[i];
}
return hashval % primes[PrimesIndex];
}
List *lookup (HashTable *hashtable,int hashval,char number[10])
{
printf("NUMBER:%s\n",number);
List *list=hashtable[hashval].head;
for(list; list!=NULL; list=list->next){
if (strcmp(number,list->number)==0)
return list;
}
return NULL;
}
int add (HashTable* hashtable,char number[10],char* name,int time)
{
List *new_elem;
int hashval=hash (hashtable,number);
new_elem=hashtable[hashval].head;
if(hashtable[hashval].length>0)
{
if ((lookup (hashtable,hashval,number))!=NULL) {return 0;}
}
if (!(new_elem=malloc(sizeof(struct List)))){ return -1;}
//insert values for the new elem
new_elem->number=strdup(number);
new_elem->name=strdup(name);
new_elem->time=time;
hashtable[hashval].head=new_elem;
new_elem->next=NULL;
hashtable[hashval].length++;
/* rehash existing entries if necessary */
if(hashTableSize(hashtable)>= 2*primes[PrimesIndex])
{
hashtable = expand(hashtable);
if (hashtable ==NULL){
return 0;
}
}
return 1;
}
HashTable* expand(HashTable* h)
{ printf("EXPAND \n");
HashTable* new;
List *temp;
int n;
List *node,*next;
PrimesIndex++;
int new_size= primes[PrimesIndex]; /* double the size,odd length */
if (!(new=malloc((sizeof( List*))*new_size))) return NULL;
for(n=0; n< h->length; ++n) {
for(node=h[n].head; node; node=next) {
add (new, node->number, node->name,node->time);
next=node->next;
//free(node);
}
}
free(h);
return new;
}
und die Haupt:
int main(int argc, char *argv[])
{
char **token;
FILE *delimitedFile;
/*Here's an example of tokenizing lines from an actual file*/
/*Open file for reading ("r"), and take a FILE pointer,
which you can use to fetch lines using fgets()*/
my_hash_table = createHashTable(17);
if(my_hash_table==NULL)
{ return 1;
}
FILE * File2;
if ((File2=fopen(" File.txt","r")) !=NULL)
{ // File.txt format: [name number time]
int li = 0;
char *lin = (char *) malloc(MAX_LINE * sizeof(char));
while(fgets(lin, MAX_LINE, File2) != NULL)
{
token = my_linetok(lin, " ");
if(token != NULL)
{
char* number ;
char* name;
int time;
int i;
for(i = 0; token[i] != NULL; i++)
{
name=strdup(token[0]);
number=strdup(token[1]);
time=atoi(token[2]);
if (i==2)
{ int insertDone=0;
insertDone =add(my_hash_table,number,name,time);
}
}
free(name);
free(number);
free(token);
}
else
{
printf("Error reading line %s\n", lin);
exit(1);
}
}
}
else
{
printf("Error opening file \nEXIT!");
exit(0);
}
return 1;
}
Ich kann mir vorstellen, dass dies nicht die Ursache Ihres segfault ist, aber wollen Sie nicht mit 'list-> number 'vergleichen, nicht mit' list-> name'? –
Außerdem bedeutet das Backtrace, dass Sie sich in einer Funktion namens 'lookup()' befinden, die von einer Funktion mit dem Namen 'add()' aufgerufen wird. Wo sind diese? –
Sie befreien 'name', aber geben Sie' number' nicht frei. Hat Ihre Funktion 'add()' Speicher zugewiesen, um sowohl 'number' als auch' name' zu enthalten, oder nur für 'number'? – DReJ