什么是与此code中的问题? [用C哈希表] [英] What's the problem with this code? [hashtable in C]

查看:67
本文介绍了什么是与此code中的问题? [用C哈希表]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现一个哈希表。以下是我的初始化它的功能。
即时得到一些错误,我无法理解这是为什么。我也引述的valgrind说。

  typedef结构的HashTable
    {
     INT大小;
     结构列表*头;
     结构列表*尾;
    }哈希表;    typedef结构列表
    {
     字符*号;
     字符*名称;
     INT时间;
     结构列表*接下来的;
    }清单;    #定义size_of_table 211    哈希表* createHashTable(无效)
    {
     哈希表* NEW_TABLE =的malloc(sizeof的(* NEW_TABLE)* size_of_table); // 606线     如果(NEW_TABLE == NULL)
     {返回NULL;
     }     INT I = 0;
     对于(I; I< size_of_table;我++)
     {
      NEW_TABLE [I] .size = 0;
      NEW_TABLE [I]。头= NULL;
      NEW_TABLE [I] .tail = NULL;
     }
     返回NULL;
    }


 尺寸为8的写入无效
== == 7738在0x401707:createHashTable(project2.c:617)
== == 7738通过0x401AF6:主(project.c:739)
== == 7738地址0x51996e0是规模1688 alloc'd块后8个字节
== == 7738在0x4C25153:的malloc(vg_replace_malloc.c:195)
== == 7738由0x401698:createHashTable(project2.c:606)
== == 7738通过0x401AF6:主(project.c:739)
== == 7738
== == 7738
== 7738 == 141中的错误的4方面3:
== == 7738尺寸为8的写入无效
== == 7738在0x4016E8:createHashTable(project2.c:616)
== == 7738通过0x401AF6:主(project.c:739)
== == 7738地址0x51996d8是规模1688 alloc'd块后0字节
== == 7738在0x4C25153:的malloc(vg_replace_malloc.c:195)
== == 7738由0x401698:createHashTable(project2.c:606)
== == 7738通过0x401AF6:主(project.c:739)



解决方案

您的确定的那就是你要测试的code? 1688字节分为211数组元素给每8个字节。

这是相当不可能的,现代的环境只会给你8个字节的结构持有 INT 和两个三分球。


通过测试的方式,下面code:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;typedef结构哈希表{
    INT大小;
    结构列表*头;
    结构列表*尾;
}哈希表;typedef结构{名单
    字符*号;
    字符*名称;
    INT时间;
    结构列表*接下来的;
}清单;#定义size_of_table 211哈希表* createHashTable(无效){
    哈希表* NEW_TABLE =的malloc(sizeof的(* NEW_TABLE)* size_of_table); // 606线
    的printf(%d个\\ N的sizeof(* NEW_TABLE));
    的printf(%d个\\ N的sizeof(NEW_TABLE));
    如果(NEW_TABLE == NULL){
        返回NULL;
    }    INT I = 0;
    对于(I; I< size_of_table;我++){
        NEW_TABLE [I] .size = 0;
        NEW_TABLE [I]。头= NULL;
        NEW_TABLE [I] .tail = NULL;
    }
    返回NEW_TABLE;
}诠释主要(无效){
    哈希表* X = createHashTable();
    免费(X);
    返回0;
}

输出:

  == == 3569 MEMCHECK,内存错误检测
== == 3569版权所有(C)2002-2009,和GNU GPL的,Julian Seward写等。
== == 3569 Valgrind的使用,3.6.0.SVN,Debian和LibVEX;与-h版权信息重新运行
== == 3569命令:./qq
== == 3569
12
4
== == 3569
== == 3569 HEAP摘要:
== == 3569使用在退出:0块0字节
== == 3569总堆的使用情况:1 allocs,1的FreeS,2,532字节分配
== == 3569
== == 3569的所有堆块被释放 - 无泄漏是可能的
== == 3569
== == 3569对于检测燮pressed错误计数,重新运行:-v
== == 3569错误摘要:从0 0上下文错误(SUP pressed:13 8)

什么是程序给你,当你通过的valgrind您的系统上运行呢?

这code我上面也提供与固定的方式(一个明确的内存泄漏)在成功时返回NULL您的问题。您在函数最后返回不应该返回NULL,它应该是:

 返回NEW_TABLE;


根据从我提供的样品code你的 24,8 输出

,请确保您的真正的使用:

 的HashTable * NEW_TABLE =的malloc(sizeof的(* NEW_TABLE)* size_of_table); // 606线

而不是:

 的HashTable * NEW_TABLE =的malloc(sizeof的(NEW_TABLE)* size_of_table); // 606线

后者将使用的指针大小 8 ,而不是的结构尺寸24 ,当我做这样的说法,我得到:

  == == 3637 MEMCHECK,内存错误检测
== == 3637版权所有(C)2002-2009,和GNU GPL的,Julian Seward写等。
== == 3637 Valgrind的使用,3.6.0.SVN,Debian和LibVEX;与-h版权信息重新运行
== == 3637命令:./qq
== == 3637
12
4
== == 3637大小为4的写入无效
== == 3637在0x80484CD:createHashTable(在/ home /艾伦/ QQ)
== == 3637通过0x8048509:主(在/ home /艾伦/ QQ)
== == 3637地址0x419a374是尺寸844 alloc'd块后0字节
== == 3637在0x4024F20:的malloc(vg_replace_malloc.c:236)
== == 3637通过0x8048465:createHashTable(在/ home /艾伦/ QQ)
== == 3637通过0x8048509:主(在/ home /艾伦/ QQ)
== == 3637
== == 3637大小为4的写入无效
== == 3637在0x80484E3:createHashTable(在/ home /艾伦/ QQ)
== == 3637通过0x8048509:主(在/ home /艾伦/ QQ)
== == 3637地址0x419a378是尺寸844 alloc'd块后4个字节
== == 3637在0x4024F20:的malloc(vg_replace_malloc.c:236)
== == 3637通过0x8048465:createHashTable(在/ home /艾伦/ QQ)
== == 3637通过0x8048509:主(在/ home /艾伦/ QQ)
== == 3637
== == 3637大小为4的写入无效
== == 3637在0x80484B8:createHashTable(在/ home /艾伦/ QQ)
== == 3637通过0x8048509:主(在/ home /艾伦/ QQ)
== == 3637地址0x419a37c是尺寸844 alloc'd块后8个字节
== == 3637在0x4024F20:的malloc(vg_replace_malloc.c:236)
== == 3637通过0x8048465:createHashTable(在/ home /艾伦/ QQ)
== == 3637通过0x8048509:主(在/ home /艾伦/ QQ)
== == 3637
== == 3637
== == 3637 HEAP摘要:
== == 3637使用在退出:0块0字节
== == 3637总堆的使用情况:1 allocs,1的FreeS,844字节分配
== == 3637
== == 3637的所有堆块被释放 - 无泄漏是可能的
== == 3637
== == 3637对于检测燮pressed错误计数,重新运行:-v
== == 3637错误摘要:从3上下文422错误(SUP pressed:13 8)


如果你确信你使用了 24 值,将行:

 的printf(%d个\\ N的sizeof(* NEW_TABLE)* size_of_table);

后的malloc 行,看看它输出。

I'm implementing a hash table. The following is my function for initializing it. Im getting some errors which I cant understand why. I have also quoted what valgrind says.

 typedef struct HashTable
    {
     int size ;  
     struct List *head; 
     struct List *tail;     
    }HashTable;

    typedef struct List
    {
     char *number;
     char *name;
     int time;
     struct List *next;     
    }List;

    #define size_of_table 211

    HashTable *createHashTable(void)
    {
     HashTable *new_table = malloc(sizeof(*new_table)*size_of_table); //line 606

     if (new_table == NULL)
     { return NULL;
     }

     int i=0;
     for(i; i<size_of_table; i++)
     { 
      new_table[i].size=0;
      new_table[i].head=NULL;
      new_table[i].tail=NULL;
     }
     return NULL;
    }

Invalid write of size 8
==7738==    at 0x401707: createHashTable (project2.c:617)
==7738==    by 0x401AF6: main (project.c:739)
==7738==  Address 0x51996e0 is 8 bytes after a block of size 1,688 alloc'd
==7738==    at 0x4C25153: malloc (vg_replace_malloc.c:195)
==7738==    by 0x401698: createHashTable (project2.c:606)
==7738==    by 0x401AF6: main (project.c:739)
==7738== 
==7738== 
==7738== 141 errors in context 3 of 4:
==7738== Invalid write of size 8
==7738==    at 0x4016E8: createHashTable (project2.c:616)
==7738==    by 0x401AF6: main (project.c:739)
==7738==  Address 0x51996d8 is 0 bytes after a block of size 1,688 alloc'd
==7738==    at 0x4C25153: malloc (vg_replace_malloc.c:195)
==7738==    by 0x401698: createHashTable (project2.c:606)
==7738==    by 0x401AF6: main (project.c:739)

解决方案

Are you sure that's the code you're testing? 1688 bytes divided into 211 array elements gives 8 bytes each.

It's rather unlikely that a modern environment would only give you 8 bytes for a structure holding an int and two pointers.


By way of testing, the following code:

#include <stdio.h>
#include <stdlib.h>

typedef struct HashTable {
    int size ;
    struct List *head;
    struct List *tail;
} HashTable;

typedef struct List {
    char *number;
    char *name;
    int time;
    struct List *next;
} List;

#define size_of_table 211

HashTable *createHashTable(void) {
    HashTable *new_table = malloc(sizeof(*new_table)*size_of_table); //line 606
    printf ("%d\n", sizeof(*new_table));
    printf ("%d\n", sizeof(new_table));
    if (new_table == NULL) {
        return NULL;
    }

    int i=0;
    for(i; i<size_of_table; i++) {
        new_table[i].size=0;
        new_table[i].head=NULL;
        new_table[i].tail=NULL;
    }
    return new_table;
}

int main(void) {
    HashTable *x = createHashTable();
    free (x);
    return 0;
}

outputs:

==3569== Memcheck, a memory error detector
==3569== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3569== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==3569== Command: ./qq
==3569== 
12
4
==3569== 
==3569== HEAP SUMMARY:
==3569==     in use at exit: 0 bytes in 0 blocks
==3569==   total heap usage: 1 allocs, 1 frees, 2,532 bytes allocated
==3569== 
==3569== All heap blocks were freed -- no leaks are possible
==3569== 
==3569== For counts of detected and suppressed errors, rerun with: -v
==3569== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 8)

What does that program give you when you run it through valgrind on your system?

That code I supply above also fixes your problem with returning NULL on success by the way (a definite memory leak). Your final return in the function should not be returning NULL, it should be:

    return new_table;


Based on your 24,8 output from the sample code I provided, make sure you're really using:

    HashTable *new_table = malloc(sizeof(*new_table)*size_of_table); //line 606

rather than:

    HashTable *new_table = malloc(sizeof(new_table)*size_of_table); //line 606

The latter will use the pointer size of 8 rather than the structure size of 24 and, when I do it that way, I get:

==3637== Memcheck, a memory error detector
==3637== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3637== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==3637== Command: ./qq
==3637== 
12
4
==3637== Invalid write of size 4
==3637==    at 0x80484CD: createHashTable (in /home/allan/qq)
==3637==    by 0x8048509: main (in /home/allan/qq)
==3637==  Address 0x419a374 is 0 bytes after a block of size 844 alloc'd
==3637==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
==3637==    by 0x8048465: createHashTable (in /home/allan/qq)
==3637==    by 0x8048509: main (in /home/allan/qq)
==3637== 
==3637== Invalid write of size 4
==3637==    at 0x80484E3: createHashTable (in /home/allan/qq)
==3637==    by 0x8048509: main (in /home/allan/qq)
==3637==  Address 0x419a378 is 4 bytes after a block of size 844 alloc'd
==3637==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
==3637==    by 0x8048465: createHashTable (in /home/allan/qq)
==3637==    by 0x8048509: main (in /home/allan/qq)
==3637== 
==3637== Invalid write of size 4
==3637==    at 0x80484B8: createHashTable (in /home/allan/qq)
==3637==    by 0x8048509: main (in /home/allan/qq)
==3637==  Address 0x419a37c is 8 bytes after a block of size 844 alloc'd
==3637==    at 0x4024F20: malloc (vg_replace_malloc.c:236)
==3637==    by 0x8048465: createHashTable (in /home/allan/qq)
==3637==    by 0x8048509: main (in /home/allan/qq)
==3637== 
==3637== 
==3637== HEAP SUMMARY:
==3637==     in use at exit: 0 bytes in 0 blocks
==3637==   total heap usage: 1 allocs, 1 frees, 844 bytes allocated
==3637== 
==3637== All heap blocks were freed -- no leaks are possible
==3637== 
==3637== For counts of detected and suppressed errors, rerun with: -v
==3637== ERROR SUMMARY: 422 errors from 3 contexts (suppressed: 13 from 8)


If you are sure you're using the 24 value, place the line:

printf ("%d\n", sizeof(*new_table)*size_of_table);

after the malloc line and see what it outputs.

这篇关于什么是与此code中的问题? [用C哈希表]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆