我正在实现哈希表。以下是我初始化它的功能。 我得到一些错误,我不明白为什么。我也引用了valgrind所说的话。
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)
答案 0 :(得分:1)
对我来说很好。我添加了const int size_of_table = 12
并从createHashTable()
调用main
。
$ valgrind ./a.out
==30237== Memcheck, a memory error detector
==30237== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==30237== Using Valgrind-3.6.0.SVN and LibVEX; rerun with -h for copyright info
==30237== Command: ./a.out
==30237==
--30237-- ./a.out:
--30237-- dSYM directory is missing; consider using --dsymutil=yes
==30237==
==30237== HEAP SUMMARY:
==30237== in use at exit: 376 bytes in 2 blocks
==30237== total heap usage: 2 allocs, 0 frees, 376 bytes allocated
==30237==
==30237== LEAK SUMMARY:
==30237== definitely lost: 288 bytes in 1 blocks
==30237== indirectly lost: 0 bytes in 0 blocks
==30237== possibly lost: 0 bytes in 0 blocks
==30237== still reachable: 88 bytes in 1 blocks
==30237== suppressed: 0 bytes in 0 blocks
==30237== Rerun with --leak-check=full to see details of leaked memory
==30237==
==30237== For counts of detected and suppressed errors, rerun with: -v
==30237== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$
答案 1 :(得分:1)
你确定那是你正在测试的代码吗?分成211个数组元素的1688字节各给出8个字节。
现代环境不太可能只为持有int
和两个指针的结构提供8个字节。
通过测试,以下代码:
#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;
}
输出:
==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)
当你通过系统上的valgrind运行它时,该程序会给你什么?
我上面提供的代码也解决了你在成功时返回NULL的问题(确定的内存泄漏)。你在函数中的最终返回不应该返回NULL,它应该是:
return new_table;
根据我提供的示例代码中的24,8
输出,确保您 使用:
HashTable *new_table = malloc(sizeof(*new_table)*size_of_table); //line 606
而不是:
HashTable *new_table = malloc(sizeof(new_table)*size_of_table); //line 606
后者将使用8
的指针大小而不是24
的结构大小,当我这样做时,我得到:
==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)
如果您确定使用的是24
值,请输入以下行:
printf ("%d\n", sizeof(*new_table)*size_of_table);
在malloc
行之后,看看它输出了什么。