gpt4 book ai didi

c - 分割。 strcmp [C]

转载 作者:行者123 更新时间:2023-11-30 19:59:21 26 4
gpt4 key购买 nike

我有一个格式为:[名称][数字][金额]的文件数字被视为字符串。我在 strcmp 中使用它。问题是我遇到了段错误。我知道在大多数情况下,当 strcmp 标记段错误时,这意味着参数之一为空或无法找到其“结束”('\0')。我检查了 gdb,我不能说这是否是问题所在。看一下:

> (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

代码:

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

主要内容:

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

最佳答案

这里的根本问题是您创建了一个包含 17 个存储桶的哈希表:

my_hash_table = createHashTable(17);

但是 C 数组是从 0 开始的,并且 PrimesIndex 从 1 开始,而不是 0,因此在 add() 内部,调用 hash() :

int hashval=hash (hashtable,number);

将返回 0 到 28 之间的数字,而不是 0 到 16 之间的数字。因此,在某些时候,将向 hashval 分配一个超出范围的值,并且后续的值之一由 hashval 索引的访问,例如

new_elem=hashtable[hashval].head;

将读取未初始化的内存,最终导致稍后出现诸如0xffffffff之类的疯狂指针值。

解决方案:int PrimesIndex = 1; 更改为 int PrimesIndex = 0;

但老实说,我认为我很可能还遗漏了其他问题。有:

  • 我在评论中指出的 main()while 循环内的 for 循环存在问题;
  • lookup_on_Clients()number 参数的可疑声明;
  • 事实上,有时该函数被称为 lookup(),有时被称为 lookup_on_Clients()(正如 Oli 所注意到的);
  • 而且我不相信 my_linetok() (您没有显示其源代码)可以正常工作 - 至少,除非它使用静态缓冲区,否则它必须分配一个 char * 数组,用于保存指向各个 token 的指针,该指针永远不会被释放——内存泄漏。

关于c - 分割。 strcmp [C],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4705325/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com