C 至少375次成功输入后出现代码Seg故障
在我正在研究的一个哈希字典中,根据GDB的说法,数组已经从500调整到1000。它试图添加的数组索引是799,所以它不是越界的。。。我不知道为什么这是赛格断层,尤其是在这样一条看似无害的线路上。这是相关代码C 至少375次成功输入后出现代码Seg故障,c,C,在我正在研究的一个哈希字典中,根据GDB的说法,数组已经从500调整到1000。它试图添加的数组索引是799,所以它不是越界的。。。我不知道为什么这是赛格断层,尤其是在这样一条看似无害的线路上。这是相关代码 int main(int argc, char **argv) { FILE *src = fopen(argv[1], "r"); int algnum = 1; char input[40]; struct HT *table = create(); if (argc == 3) {
int main(int argc, char **argv)
{
FILE *src = fopen(argv[1], "r");
int algnum = 1;
char input[40];
struct HT *table = create();
if (argc == 3)
{
if (strcmp(argv[2], "0") == 0)
{
algnum = 0;
}
else if (strcmp(argv[2], "1") == 0)
{
algnum = 1;
}
}
while(fgets(input, 40, src) != 0)
{
int i = 0;
while(input[i] != '\0')
{
i++;
}
struct word *wrd = malloc(sizeof(struct word));
wrd->letters = input;
wrd->length = i;
if (algnum = 0)
{
add(table, wrd, &alg0);
}
else if (algnum = 1)
{
add(table, wrd, &alg1);
}
}
}
然后在包含文件中
struct HT* create()
{
struct HT* table = malloc(sizeof(struct HT));
table->entries = 0;
table->num_buckets = 500;
table->largest_bucket = 0;
table->occupied_buckets = 0;
table->buckets = malloc(500 * sizeof(struct bucket*));
int i;
for (i = 0; i<500; i++)
{
table->buckets[i] = malloc(sizeof(struct bucket));
table->buckets[i]->num_items = 0;
}
return table;
}
struct HT* resize(struct HT* table, int(*alg)(struct word *wrd))
{
struct HT* table_new = malloc(sizeof(struct HT));
int new_size = 2*table->num_buckets;
table_new->buckets = malloc(new_size*sizeof(struct bucket*));
int i;
for (i = 0; i < new_size; i++)
{
table->buckets[i] = malloc(sizeof(struct bucket));
table->buckets[i]->num_items = 0;
}
table_new->num_buckets = new_size;
table_new->occupied_buckets = 0;
table_new->entries = 0;
table_new->largest_bucket = 0;
struct word* wrd_temp = malloc(sizeof(struct word));
struct item* item_temp = malloc(sizeof(struct item));
for (i = 0; i<table->num_buckets; i++)
{
item_temp = table->buckets[i]->head;
while(item_temp != 0)
{
wrd_temp = item_temp->wrd;
add(table_new, wrd_temp, alg);
item_temp = item_temp->next;
}
}
quit(table);
return table_new;
}
void add(struct HT* table, struct word *wrd, int(*alg)(struct word *wrd))
{
if ((double)table->entries / (double)table->num_buckets > .75)
{
table = resize(table, alg);
}
sort(wrd);
int code = alg(wrd);
code = code % table->num_buckets;
struct item* item_temp = malloc(sizeof(struct item));
struct item* item_add = malloc(sizeof(struct item));
item_add->wrd = wrd;
if (table->buckets[code]->head == 0)
{
table->buckets[code]->head = item_add;
table->occupied_buckets++;
}
else
{
item_temp = table->buckets[code]->head;
while (item_temp->next != 0) {
item_temp = item_temp->next;
}
item_temp->next = item_add;
}
table->buckets[code]->num_items++;
table->entries++;
if (table->buckets[code]->num_items > table->largest_bucket)
{
table->largest_bucket = table->buckets[code]->num_items;
}
}
struct HT*create()
{
struct-HT*table=malloc(sizeof(struct-HT));
表->条目=0;
表->桶数=500;
表->最大桶=0;
表->占用的桶=0;
表->bucket=malloc(500*sizeof(struct bucket*));
int i;
对于(i=0;ibuckets[i]=malloc(sizeof(struct bucket));
表->存储桶[i]->num_items=0;
}
返回表;
}
结构HT*调整大小(结构HT*表格,整数(*alg)(结构字*wrd))
{
struct HT*table_new=malloc(sizeof(struct HT));
int new_size=2*表->num_桶;
table_new->bucket=malloc(new_size*sizeof(struct bucket*));
int i;
对于(i=0;ibucket[i]=malloc(sizeof(struct bucket));
表->存储桶[i]->num_items=0;
}
table_new->num_bucket=new_size;
表\u新建->占用的\u存储桶=0;
表\u新建->条目=0;
表\u新建->最大\u桶=0;
结构词*wrd_temp=malloc(sizeof(结构词));
结构项目*项目_temp=malloc(结构项目的大小);
用于(i=0;单位桶;i++)
{
物料温度=表->铲斗[i]->头部;
而(项目温度!=0)
{
工作温度=物料温度->工作温度;
添加(新表、工作温度、alg);
项目临时=项目临时->下一步;
}
}
退出(表);
返回表_新;
}
无效添加(结构HT*表格、结构word*wrd、int(*alg)(结构word*wrd))
{
如果((双)表->条目/(双)表->数量桶>.75)
{
表=调整大小(表,alg);
}
排序(wrd);
内部代码=alg(wrd);
代码=代码%table->num\u bucket;
结构项目*项目_temp=malloc(结构项目的大小);
结构项目*项目添加=malloc(sizeof(结构项目));
物料添加->工作日=工作日;
如果(表->桶[代码]->头==0)
{
表->桶[代码]->头=项目添加;
表->占用的桶++;
}
其他的
{
物料温度=表->铲斗[代码]->头部;
同时(项目临时->下一步!=0){
项目临时=项目临时->下一步;
}
项目临时->下一步=项目添加;
}
表->存储桶[code]->num_items++;
表->条目++;
if(表格->存储桶[代码]->num\u items>表格->最大存储桶)
{
表->最大\u桶=表->桶[代码]->数量\u项;
}
}
编辑:它崩溃的行是:
程序接收信号SIGSEGV,分段故障。
在ht.c:118处添加0x0000000000400cbd(表=0x613cc0,wrd=0x613ca0,alg=0x400942)
118如果(表->桶[代码]->头==0)
请求的信息:
(gdb)打印表格->存储桶[799]
$2=(struct bucket*)0x0问题在于,在
resize
中,您创建了一个全新的HT
结构。但在add
中,您不会将其传回调用链,因此在main
中,您仍然拥有旧的HT
结构
另外,你永远不会释放任何东西,所以你有很多内存泄漏
在
main
中创建一个新表。让我们调用此表1。稍后,当表满时,您创建一个新表,让我们调用此表2。此新表由resize
返回,并在add
中使用。但是当add
返回main
函数时,仍然有指向表1的指针
因此,当下次调用
add
时,main
函数将通过表1,表1太小,因此调用resize
,并创建另一个表3,该表仅在add
中本地使用。以此类推……问题是在resize
中创建一个全新的HT
structure.但是在add
中,您不会将其传递回调用链,因此在main
中,您仍然拥有旧的HT
结构
另外,你永远不会释放任何东西,所以你有很多内存泄漏
在
main
中创建一个新表。让我们调用此表1。稍后,当表满时,您创建一个新表,让我们调用此表2。此新表由resize
返回,并在add
中使用。但是当add
返回main
函数时,仍然有指向表1的指针
因此,当下次调用
add
时,main
函数将通过表1,表1太小,因此调用resize
,并创建另一个表3,该表仅在add
中本地使用。以此类推……所有条目字母
成员都将是相同的。您让它们都指向相同的位置读取文件时将更新的数组。表->存储桶[代码]的值是多少就在分割之前?至于错误,哪一行是第118行?另外,在调整分配内存的大小时,不是更容易使用吗?@JoachimPileborg我想哈希代码取决于表的大小,因此在调整大小后,需要将内容放入不同的存储桶中。所有条目字母
成员都将是相同的。您可以让它们都指向同一个数组,该数组将在读取文件时更新。table->bucket[code]的值是多少就在分割之前?至于错误,哪一行是第118行?另外,在调整分配内存的大小时,它不是更容易使用吗?@JoachimPileborg我想哈希代码取决于表的大小,所以在调整大小后,需要将内容放入不同的存储桶中。我不这么认为。当我在seg故障的e时间我得到1000,这意味着它已经调整了大小。@SwiftCore这是因为您随后再次调用了resize
。实际上,在第一次之后,您每次都会在add
中调用resize
,甚至没有将新数据添加到正确的位置。但是在我调用它之后,它有一个新的num_bucket,因此它应该跳过over调整分支大小?@Swif