简体   繁体   English

至少成功登录375次后出现代码段错误

[英]Code Seg Faults after atleast 375 Successful Entries

In a hash dictionary I'm working on, according to GDB the array has resized once from 500 to 1000. The array index it crashes trying to add is 799, so it's not out of bounds... I'm not sure why it's seg faulting, especially on such a seemingly harmless line. 在我正在研究的哈希字典中,根据GDB,数组的大小一次从500调整为1000。尝试添加时崩溃的数组索引为799,所以它不是没有界限的...我不确定为什么会这样段故障,特别是在这种看似无害的线路上。 Here's the relevant code. 这是相关的代码。

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

Then in the include file... 然后在包含文件中...

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

EDIT: The line it's crashing on is: 编辑:崩溃的行是:

Program received signal SIGSEGV, Segmentation fault. 程序收到信号SIGSEGV,分段故障。 0x0000000000400cbd in add (table=0x613cc0, wrd=0x613ca0, alg=0x400942 ) at ht.c:118 118 if (table->buckets[code]->head == 0) 如果(table-> buckets [code]-> head == 0)在ht.c:118 118处添加0x0000000000400cbd(table = 0x613cc0,wrd = 0x613ca0,alg = 0x400942)

REQUESTED INFO: 要求的信息:

(gdb) print table->buckets[799] $2 = (struct bucket *) 0x0 (gdb)打印表-> buckets [799] $ 2 =(struct bucket *)0x0

The problem is that in resize you create a completely new HT structure. 问题在于,在resize您将创建一个全新的HT结构。 But in add you don't pass this back up the call-chain, so in main you still have your old HT structure. add您不会将此传递回调用链,因此, main您仍然具有旧的 HT结构。

And as an extra side-note, you never free anything so you have lots of memory leaks. 另外,您永远不会free任何东西,因此会发生大量内存泄漏。


In main you create a new table. main创建一个新表。 Lets call this table 1. Later when it's getting full you're creating a new table, lets call this 2. This new table is returned by resize and used in add . 让我们叫这个表1。稍后,当它变满时,您要创建一个表,让我们叫它2。这个新表由resize返回并在add But when add returns the main function still has a pointer to table 1. 但是当add返回时, main函数仍然具有指向表1的指针。

So when add is called next time, the main function passes table 1, which is too small so resize is called and creates yet another table, 3, that is used only locally in add . 因此,下次调用add时, main函数将传递表1,该表太小,因此将调用resize并创建另一个表3,该表仅在add本地使用。 And so on and so on... 等等等等...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM