为什么 gcc 中的分段错误时 malloc.



我写了一段代码来实现哈希函数。将第 9 个元素"a12a"添加到列表中时出现问题,gdb 报告如下,似乎问题发生在 malloc 应用内存期间。但是在添加第 9 个元素之前,我曾经在添加第 6 个元素"ad"时通过 malloc 成功应用过一次内存,为什么第二次应用内存失败?

Breakpoint 1, insert (p=0x3d2d10, value=0x4030e8 "a12a") at hashop.c:39
39              id = hash(value);
(gdb) n
40              *current = p + id;
(gdb)
41              if((*current)->value == NULL) {
(gdb)
44                      if((lookup(p+id, value)) == NULL) {
(gdb)
45                              new = (nList *)malloc(sizeof(nList));
(gdb)
Program received signal SIGSEGV, Segmentation fault.
0x7c938996 in ntdll!RtlDuplicateUnicodeString ()
   from C:WINDOWSsystem32ntdll.dll
(gdb)

我的代码是:

void insert(nList *p, char *value)
{
    nList *new, **current;
    int id;
    id = hash(value);
    *current = p + id;
    if((*current)->value == NULL) {
        (*current)->value = value;
    } else {
        if((lookup(p+id, value)) == NULL) {
            new = (nList *)malloc(sizeof(nList));
            new->value = value;
            new->next = NULL;       
            while((*current)->next != NULL) {
                (*current) =(*current)->next;
            }
            (*current)->next = new;
        }
    }
}   
static char *str2[] = {"ac", "ba", "abv", "bc", "bx", "ad", "xx", "aaa", "a12a", "b123"};

每个元素的哈希 id 如下:

ac, HashId=6
ba, HashId=5
abv, HashId=3
bc, HashId=7
bx, HashId=8
ad, HashId=7
xx, HashId=0
aaa, HashId=1
a12a, HashId=3
b123, HashId=8

从上面的列表中,可以肯定"bc"和"ad"具有相同的哈希ID,因此在我的insert()函数中,我将应用一个内存块来存储"ad"。"abv"和"a12a"也是如此,我也应用了一个内存块,但这次失败了。为什么?有人能弄清楚吗?赞赏!

你用这行破坏了内存:

*current = p + id;

-Wall传递给 gcc 以打开所有警告,您将看到:

buggy-hash.c: In function ‘insert’:
buggy-hash.c:19:14: warning: ‘current’ is used uninitialized in this function [-Wuninitialized]

提示:在 Linux 下使用 gcc -Wall 并在内存调试器(如 Valgrind 等)下运行程序将使发现这些内存问题变得更加容易。

我猜你是在Windows下使用CodeBlocks或其他IDE来学习C编程吗?在Visual Studio中以调试模式构建程序也会发现这些问题。

问题是我使用了 p+id 作为查找函数的输入,但忘记了 p 已经被 *current 更改了。 所以正确的代码是:

void insert(nList *p, char *value)
{
    nList *new, **current = &p;
    int id;
    id = hash(value);
    *current += id;
    if((*current)->value == NULL) {
        (*current)->value = value;
    } else {
        if((lookup(*current, value)) == NULL) {
            new = (nList *)malloc(sizeof(nList));
            if(new == NULL)
                printf("nCannot get memory");
            else {
                new->value = value;
                new->next = NULL;       
                while((*current)->next != NULL) {
                    (*current) =(*current)->next;
                }
                (*current)->next = new;
            }
        }
    }
}   

相关内容

  • 没有找到相关文章

最新更新