调整哈希表大小 - 帮助我 Valgrind 调试我的程序
我正在尝试创建一个包含联系电话和名称的哈希表,当我的联系人太多时,我需要调整哈希表的大小。当我这样做时,我的内存泄漏 +阀门错误。我尝试了很多事情,您能帮我理解或解决问题吗?
我的哈希表结构:
struct dir {
uint32_t len;
uint32_t contactsNumber;
struct contact *contactList;
};
我的联系
结构:
struct contact *contact_create(char *name, char *num) {
struct contact *init_contact = malloc(sizeof(struct contact));
init_contact->name = name;
init_contact->num = num;
init_contact->next = NULL;
return (init_contact);
}
我的ressize
函数:
void dir_resize(struct dir *dir, uint32_t new_size) {
uint32_t old_size = dir->len;
struct dir *new_dir = dir_create(new_size);
for (uint32_t i = 0; i < old_size; i++) {
struct contact *current_contact = dir[i].contactList;
while (current_contact->next != NULL) {
dir_insert(new_dir, current_contact->next->name, current_contact->next->num);
// contact_removeTop(current_contact->next);
current_contact->next = current_contact->next->next;
}
free(current_contact);
}
// dir_free(dir);
// dir = realloc(dir, sizeof(struct dir)*new_size);
dir->contactsNumber = new_dir->contactsNumber;
dir->len = new_size;
for (uint32_t i = 0; i < new_size; i++) {
dir[i].contactList = new_dir[i].contactList;
}
//dir_free(new_dir);
//dir_print(dir);
}
我的dir_free
函数:
void dir_free(struct dir *dir) {
uint32_t size = dir->len;
for (uint32_t i = 0; i < size; i++) {
contact_free(dir[i].contactList);
}
free(dir);
return;
}
我的contact_free
函数:
void contact_free(struct contact *contact) {
if (contact == NULL) {
return;
}
while (contact->next != NULL) {
contact_removeTop(contact);
}
free(contact);
}
我的dir_create
函数:
struct dir *dir_create(uint32_t len) {
struct dir *directory = malloc(sizeof(struct dir) * len);
//struct dir *directory = malloc(sizeof(struct dir) * len);
directory->contactsNumber = 0;
for (uint32_t i = 0; i < len; i++) {
directory[i].contactList = contact_sentinel();
}
directory->len = len;
return (directory);
}
的调整
#include <stdlib.h>
#include <stdio.h>
#include <directory.h>
int main(void) {
struct dir *dir = dir_create(10);
dir_insert(dir, "A", "06789435351");
dir_insert(dir, "B", "0678346533");
dir_print(dir);
dir_insert(dir, "C", "06723236533");
dir_print(dir);
dir_insert(dir, "D", "06723236533");
dir_print(dir);
dir_resize(dir, 11);
dir_print(dir);
dir_free(dir);
return EXIT_SUCCESS;
}
。
==80271== Memcheck, a memory error detector
==80271== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==80271== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==80271== Command: ./tests/resizing-test
==80271==
------------------------ANNUAIRE-----------------------
Nombre de contacts :2
Taille de l'annuaire :10
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Name -> A, Number -> 06789435351
END.
Name -> B, Number -> 0678346533
END.
--------------------------------------------------------
------------------------ANNUAIRE-----------------------
Nombre de contacts :3
Taille de l'annuaire :10
Name -> C, Number -> 06723236533
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Name -> A, Number -> 06789435351
END.
Name -> B, Number -> 0678346533
END.
--------------------------------------------------------
------------------------ANNUAIRE-----------------------
Nombre de contacts :4
Taille de l'annuaire :10
Name -> C, Number -> 06723236533
END.
Name -> D, Number -> 06723236533
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Name -> A, Number -> 06789435351
END.
Name -> B, Number -> 0678346533
END.
--------------------------------------------------------
==80271== Invalid write of size 8
==80271== at 0x484B57C: dir_resize (directory.c:162)
==80271== by 0x10916E: main (resizing.c:16)
==80271== Address 0x4a5a0e8 is 8 bytes after a block of size 160 alloc'd
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B33B: dir_create (directory.c:24)
==80271== by 0x1090EE: main (resizing.c:8)
==80271==
------------------------ANNUAIRE-----------------------
Nombre de contacts :4
Taille de l'annuaire :11
Name -> B, Number -> 0678346533
END.
Name -> C, Number -> 06723236533
END.
Name -> D, Number -> 06723236533
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
==80271== Invalid read of size 8
==80271== at 0x484B498: dir_print (directory.c:133)
==80271== by 0x109176: main (resizing.c:17)
==80271== Address 0x4a5a0e8 is 8 bytes after a block of size 160 alloc'd
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B33B: dir_create (directory.c:24)
==80271== by 0x1090EE: main (resizing.c:8)
==80271==
Name -> A, Number -> 06789435351
END.
--------------------------------------------------------
==80271== Invalid read of size 8
==80271== at 0x484B408: dir_free (directory.c:110)
==80271== by 0x10917E: main (resizing.c:18)
==80271== Address 0x4a5a0e8 is 8 bytes after a block of size 160 alloc'd
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B33B: dir_create (directory.c:24)
==80271== by 0x1090EE: main (resizing.c:8)
==80271==
==80271==
==80271== HEAP SUMMARY:
==80271== in use at exit: 272 bytes in 5 blocks
==80271== total heap usage: 32 allocs, 27 frees, 2,056 bytes allocated
==80271==
==80271== 24 bytes in 1 blocks are definitely lost in loss record 1 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B752: contact_insert (contact.c:37)
==80271== by 0x484B5D8: dir_insert (directory.c:47)
==80271== by 0x109107: main (resizing.c:9)
==80271==
==80271== 24 bytes in 1 blocks are definitely lost in loss record 2 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B752: contact_insert (contact.c:37)
==80271== by 0x484B5D8: dir_insert (directory.c:47)
==80271== by 0x10911D: main (resizing.c:10)
==80271==
==80271== 24 bytes in 1 blocks are definitely lost in loss record 3 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B752: contact_insert (contact.c:37)
==80271== by 0x484B5D8: dir_insert (directory.c:47)
==80271== by 0x10913B: main (resizing.c:12)
==80271==
==80271== 24 bytes in 1 blocks are definitely lost in loss record 4 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B752: contact_insert (contact.c:37)
==80271== by 0x484B5D8: dir_insert (directory.c:47)
==80271== by 0x109159: main (resizing.c:14)
==80271==
==80271== 176 bytes in 1 blocks are definitely lost in loss record 5 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B33B: dir_create (directory.c:24)
==80271== by 0x484B4F1: dir_resize (directory.c:145)
==80271== by 0x10916E: main (resizing.c:16)
==80271==
==80271== LEAK SUMMARY:
==80271== definitely lost: 272 bytes in 5 blocks
==80271== indirectly lost: 0 bytes in 0 blocks
==80271== possibly lost: 0 bytes in 0 blocks
==80271== still reachable: 0 bytes in 0 blocks
==80271== suppressed: 0 bytes in 0 blocks
==80271==
==80271== For lists of detected and suppressed errors, rerun with: -s
==80271== ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 0 from 0)
最后,我 首先,我没有释放ressize
函数中的空间,您可以查看我的评论行,看看我已经尝试过释放new_dir
和dir
,但这只会导致更多错误,因此我放弃了。我不知道该怎么做,而没有弹出一百万个错误! 其次,当我使哈希表更大时,分配给DIR的内存空间不再与其新尺寸相对应,从而导致错误。正如您在评论的行中看到的那样,我尝试重新分配循环内部和外部,但错误仍然存在。我该怎么办?
感谢您的帮助!
edit :
这是我的contact_sentinel
函数:
struct contact *contact_sentinel() {
struct contact *sentinel = malloc(sizeof(struct contact));
sentinel->name = NULL;
sentinel->num = NULL;
sentinel->next = NULL;
return (sentinel);
}
我的dir_insert
:
char *dir_insert(struct dir *dir, const char *name, const char *num) {
uint32_t size = dir->len;
uint32_t index = hash_modulo(name, size);
char *number = contact_insert(dir[index].contactList, name, num);
if (number == NULL) {
dir->contactsNumber++;
}
if (dir->contactsNumber > 0.75 * size) {
dir_resize(dir, size * 2);
}
return number;
}
我的contact insert
:
char *contact_insert(struct contact *contact, const char *name, const char *num) {
while (contact->next != NULL) {
if (contact->name == name) {
const char *old_num = contact->num;
contact->num = (char *)num;
return (char *)old_num;
}
contact = contact->next;
}
if (contact->name == name) {
const char *old_num = contact->num;
contact->num = (char *)num;
return (char *)old_num;
}
contact->next = malloc(sizeof(struct contact));
assert(contact->next != NULL);
contact->next->name = (char *)name;
contact->next->num = (char *)num;
contact->next->next = NULL;
return (NULL);
}
function hash 代码>:
#include <stdlib.h>
#include <stdint.h>
uint32_t hash(const char *str) {
uint32_t hash = 5381;
uint32_t c;
while ((c = *str++)) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
uint32_t hash_modulo(const char *name, uint32_t size) {
return hash(name) % size;
}
函数dir_print
:
void dir_print(struct dir *dir) {
if (dir == NULL) {
printf("Annuaire vide.\n");
return;
}
printf("------------------------ANNUAIRE-----------------------\n");
printf("Nombre de contacts :%d\n", dir->contactsNumber);
printf("Taille de l'annuaire :%d\n", dir->len);
uint32_t len = dir->len;
for (uint32_t i = 0; i < len; i++) {
contact_print(dir[i].contactList);
}
printf("--------------------------------------------------------\n");
}
功能contact_print
:
void contact_print(struct contact *contact) {
contact = contact->next;
if (contact == NULL) {
printf("Liste vide.\n");
}
while (contact != NULL) {
printf("Name -> %s, Number -> %s\n", contact->name, contact->num);
contact = contact->next;
}
printf("END.\n");
}
I'm trying to create a hash table that contains contact numbers and names, when I have too many contacts, I need to resize my hash table. When I do that, I'm having memory leaks + valgrind errors. I've tried many things, can you help me understand or solve the issues?
My hash table structure:
struct dir {
uint32_t len;
uint32_t contactsNumber;
struct contact *contactList;
};
My contact
structure:
struct contact *contact_create(char *name, char *num) {
struct contact *init_contact = malloc(sizeof(struct contact));
init_contact->name = name;
init_contact->num = num;
init_contact->next = NULL;
return (init_contact);
}
My resize
function:
void dir_resize(struct dir *dir, uint32_t new_size) {
uint32_t old_size = dir->len;
struct dir *new_dir = dir_create(new_size);
for (uint32_t i = 0; i < old_size; i++) {
struct contact *current_contact = dir[i].contactList;
while (current_contact->next != NULL) {
dir_insert(new_dir, current_contact->next->name, current_contact->next->num);
// contact_removeTop(current_contact->next);
current_contact->next = current_contact->next->next;
}
free(current_contact);
}
// dir_free(dir);
// dir = realloc(dir, sizeof(struct dir)*new_size);
dir->contactsNumber = new_dir->contactsNumber;
dir->len = new_size;
for (uint32_t i = 0; i < new_size; i++) {
dir[i].contactList = new_dir[i].contactList;
}
//dir_free(new_dir);
//dir_print(dir);
}
My dir_free
function:
void dir_free(struct dir *dir) {
uint32_t size = dir->len;
for (uint32_t i = 0; i < size; i++) {
contact_free(dir[i].contactList);
}
free(dir);
return;
}
My contact_free
function:
void contact_free(struct contact *contact) {
if (contact == NULL) {
return;
}
while (contact->next != NULL) {
contact_removeTop(contact);
}
free(contact);
}
My dir_create
function:
struct dir *dir_create(uint32_t len) {
struct dir *directory = malloc(sizeof(struct dir) * len);
//struct dir *directory = malloc(sizeof(struct dir) * len);
directory->contactsNumber = 0;
for (uint32_t i = 0; i < len; i++) {
directory[i].contactList = contact_sentinel();
}
directory->len = len;
return (directory);
}
Finally, my resizing.c test file:
#include <stdlib.h>
#include <stdio.h>
#include <directory.h>
int main(void) {
struct dir *dir = dir_create(10);
dir_insert(dir, "A", "06789435351");
dir_insert(dir, "B", "0678346533");
dir_print(dir);
dir_insert(dir, "C", "06723236533");
dir_print(dir);
dir_insert(dir, "D", "06723236533");
dir_print(dir);
dir_resize(dir, 11);
dir_print(dir);
dir_free(dir);
return EXIT_SUCCESS;
}
The Valgrind output:
==80271== Memcheck, a memory error detector
==80271== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==80271== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==80271== Command: ./tests/resizing-test
==80271==
------------------------ANNUAIRE-----------------------
Nombre de contacts :2
Taille de l'annuaire :10
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Name -> A, Number -> 06789435351
END.
Name -> B, Number -> 0678346533
END.
--------------------------------------------------------
------------------------ANNUAIRE-----------------------
Nombre de contacts :3
Taille de l'annuaire :10
Name -> C, Number -> 06723236533
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Name -> A, Number -> 06789435351
END.
Name -> B, Number -> 0678346533
END.
--------------------------------------------------------
------------------------ANNUAIRE-----------------------
Nombre de contacts :4
Taille de l'annuaire :10
Name -> C, Number -> 06723236533
END.
Name -> D, Number -> 06723236533
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Name -> A, Number -> 06789435351
END.
Name -> B, Number -> 0678346533
END.
--------------------------------------------------------
==80271== Invalid write of size 8
==80271== at 0x484B57C: dir_resize (directory.c:162)
==80271== by 0x10916E: main (resizing.c:16)
==80271== Address 0x4a5a0e8 is 8 bytes after a block of size 160 alloc'd
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B33B: dir_create (directory.c:24)
==80271== by 0x1090EE: main (resizing.c:8)
==80271==
------------------------ANNUAIRE-----------------------
Nombre de contacts :4
Taille de l'annuaire :11
Name -> B, Number -> 0678346533
END.
Name -> C, Number -> 06723236533
END.
Name -> D, Number -> 06723236533
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
Liste vide.
END.
==80271== Invalid read of size 8
==80271== at 0x484B498: dir_print (directory.c:133)
==80271== by 0x109176: main (resizing.c:17)
==80271== Address 0x4a5a0e8 is 8 bytes after a block of size 160 alloc'd
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B33B: dir_create (directory.c:24)
==80271== by 0x1090EE: main (resizing.c:8)
==80271==
Name -> A, Number -> 06789435351
END.
--------------------------------------------------------
==80271== Invalid read of size 8
==80271== at 0x484B408: dir_free (directory.c:110)
==80271== by 0x10917E: main (resizing.c:18)
==80271== Address 0x4a5a0e8 is 8 bytes after a block of size 160 alloc'd
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B33B: dir_create (directory.c:24)
==80271== by 0x1090EE: main (resizing.c:8)
==80271==
==80271==
==80271== HEAP SUMMARY:
==80271== in use at exit: 272 bytes in 5 blocks
==80271== total heap usage: 32 allocs, 27 frees, 2,056 bytes allocated
==80271==
==80271== 24 bytes in 1 blocks are definitely lost in loss record 1 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B752: contact_insert (contact.c:37)
==80271== by 0x484B5D8: dir_insert (directory.c:47)
==80271== by 0x109107: main (resizing.c:9)
==80271==
==80271== 24 bytes in 1 blocks are definitely lost in loss record 2 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B752: contact_insert (contact.c:37)
==80271== by 0x484B5D8: dir_insert (directory.c:47)
==80271== by 0x10911D: main (resizing.c:10)
==80271==
==80271== 24 bytes in 1 blocks are definitely lost in loss record 3 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B752: contact_insert (contact.c:37)
==80271== by 0x484B5D8: dir_insert (directory.c:47)
==80271== by 0x10913B: main (resizing.c:12)
==80271==
==80271== 24 bytes in 1 blocks are definitely lost in loss record 4 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B752: contact_insert (contact.c:37)
==80271== by 0x484B5D8: dir_insert (directory.c:47)
==80271== by 0x109159: main (resizing.c:14)
==80271==
==80271== 176 bytes in 1 blocks are definitely lost in loss record 5 of 5
==80271== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==80271== by 0x484B33B: dir_create (directory.c:24)
==80271== by 0x484B4F1: dir_resize (directory.c:145)
==80271== by 0x10916E: main (resizing.c:16)
==80271==
==80271== LEAK SUMMARY:
==80271== definitely lost: 272 bytes in 5 blocks
==80271== indirectly lost: 0 bytes in 0 blocks
==80271== possibly lost: 0 bytes in 0 blocks
==80271== still reachable: 0 bytes in 0 blocks
==80271== suppressed: 0 bytes in 0 blocks
==80271==
==80271== For lists of detected and suppressed errors, rerun with: -s
==80271== ERROR SUMMARY: 8 errors from 8 contexts (suppressed: 0 from 0)
As you can see I have two problems. First, I'm not freeing up the space within the resize
function, you can look at my commented lines and see that I've already tried freeing up new_dir
and dir
but that only resulted in more errors so I gave that up. I don't know how to do it without having a million errors pop up!
Second, when I make my hash table bigger, the memory space allocated to dir no longer corresponds to its new size, which results in the errors. As you can see with my commented lines, I tried reallocating both within and outside the loop, but the error persists. What can I do about it?
Thanks for your help!
EDIT:
This is my contact_sentinel
function:
struct contact *contact_sentinel() {
struct contact *sentinel = malloc(sizeof(struct contact));
sentinel->name = NULL;
sentinel->num = NULL;
sentinel->next = NULL;
return (sentinel);
}
My dir_insert
:
char *dir_insert(struct dir *dir, const char *name, const char *num) {
uint32_t size = dir->len;
uint32_t index = hash_modulo(name, size);
char *number = contact_insert(dir[index].contactList, name, num);
if (number == NULL) {
dir->contactsNumber++;
}
if (dir->contactsNumber > 0.75 * size) {
dir_resize(dir, size * 2);
}
return number;
}
My contact insert
:
char *contact_insert(struct contact *contact, const char *name, const char *num) {
while (contact->next != NULL) {
if (contact->name == name) {
const char *old_num = contact->num;
contact->num = (char *)num;
return (char *)old_num;
}
contact = contact->next;
}
if (contact->name == name) {
const char *old_num = contact->num;
contact->num = (char *)num;
return (char *)old_num;
}
contact->next = malloc(sizeof(struct contact));
assert(contact->next != NULL);
contact->next->name = (char *)name;
contact->next->num = (char *)num;
contact->next->next = NULL;
return (NULL);
}
Function hash
:
#include <stdlib.h>
#include <stdint.h>
uint32_t hash(const char *str) {
uint32_t hash = 5381;
uint32_t c;
while ((c = *str++)) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
uint32_t hash_modulo(const char *name, uint32_t size) {
return hash(name) % size;
}
Function dir_print
:
void dir_print(struct dir *dir) {
if (dir == NULL) {
printf("Annuaire vide.\n");
return;
}
printf("------------------------ANNUAIRE-----------------------\n");
printf("Nombre de contacts :%d\n", dir->contactsNumber);
printf("Taille de l'annuaire :%d\n", dir->len);
uint32_t len = dir->len;
for (uint32_t i = 0; i < len; i++) {
contact_print(dir[i].contactList);
}
printf("--------------------------------------------------------\n");
}
Function contact_print
:
void contact_print(struct contact *contact) {
contact = contact->next;
if (contact == NULL) {
printf("Liste vide.\n");
}
while (contact != NULL) {
printf("Name -> %s, Number -> %s\n", contact->name, contact->num);
contact = contact->next;
}
printf("END.\n");
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先 - 你的大小调整。
您不需要释放联系人列表,只需重新分配目录数组。
新的 dir 结构保留了指向仍然有效的接触链的旧指针,
更重要的是,您没有返回新创建的目录。所有后续操作(主要)仍然尝试在旧目录(您可能已在此处释放)上工作。所以我让它返回新的目录,
这样就不会泄漏
其他错误,
您只在联系人列表中存储文本指针。目前有效,因为它们是文字。但是尝试这个
输出
(使用我的打印功能),
因为您将“电话”的地址存储在“contact.num”中,现在两个联系人都有相同的电话号码。
您需要执行
strdup 将为字符串分配空间并将其复制到新空间中。您需要记住最后释放内存。
而且你和你的哨兵非常不一致。您是否希望末尾始终有一个“空白”联系人?事实上你并没有这样做。实际上你根本不需要这些哨兵,只需在第一次创建它时将 dir.contactList 设置为 NULL 即可。目前,您无缘无故地分配了额外的内存块。
在这里,
您显然是在查看该名称是否已在列表中。这
只是有效的,因为您正在存储文字的地址,因此它是比较地址。应该可以
修复
将 strdup 放入 ,添加 strcmp ,修复调整大小。无泄漏
调整大小
清理触点
输出
First - your resize.
You do not need to free the contact lists, you just need to reallocate the dir array.
The new dir structure keeps the old pointers to still valid contact chains
More importantly you did not return the newly creeated directory. All you subsequent operations (in main) still tried to work on the old dir (that you might have freed here). So I made it return the new dir
so no leaks now
other errors
you are only storing text pointers in you contact list. Works at the moment becuase they are literals. But try this
output is
(using my print function)
because you stored the address of 'phone' in the 'contact.num' now both contacts have the same phone number.
you need to do
strdup will malloc space for the string and copy it into the new space for you. You will need to remeber to free the memory at the end.
Also you are very inconsistent with your sentinel. Do you intend that there is always a 'blank' contact at the end. You in fact do not do that. Really you dont need those sentinels at all , just set dir.contactList to NULL when first creating it. At the moment you are allocating an extra memory block for no reason.
here
you are clearly looking to see if that name is already in the list. This
is only working becuase you are stoing the address of literals, so its comparing addresses. It should be
OK refixed
put strdup in , added strcmp , fixed resize. No leaks
resize
clean up contacts
output