【发布时间】:2017-11-13 16:05:42
【问题描述】:
这是一个双向链表,节点/链接携带存储在列表中所需的信息(侵入式):
dlist.h:
#ifndef DLIST_H
#define DLIST_H
//--------------------------------------------------------------------------
typedef struct Link
{
struct Link* succ;
struct Link* prev;
} Link;
//--------------------------------------------------------------------------
typedef struct List
{
Link* first;
Link* last;
} List;
//--------------------------------------------------------------------------
void init(List* lst)
{
assert(lst);
lst->first = 0;
lst->last = 0;
}
//--------------------------------------------------------------------------
List* create()
{
List* lst = (List*) malloc(sizeof(List*));
init(lst);
return lst;
}
//--------------------------------------------------------------------------
void push_back(List* lst, Link* l)
{
assert(l);
assert(lst);
{
Link* last = lst->last;
if (last)
{
last->succ = l;
l->prev = last;
}
else
{
lst->first = l;
l->prev = 0;
}
lst->last = l;
l->succ = 0;
}
}
//--------------------------------------------------------------------------
void clear (List* lst)
{
assert(lst);
{
Link* curr = lst->first;
Link* next = 0;
while (curr)
{
next = curr->succ;
free(curr);
curr = next;
}
lst->first = 0;
lst->last = 0;
}
}
//--------------------------------------------------------------------------
void destroy (List* lst)
{
assert(lst);
clear(lst);
free(lst);
}
//--------------------------------------------------------------------------
typedef struct Name
{
Link l;
char* s;
} Name;
//--------------------------------------------------------------------------
Name* make_name(char* str)
{
Name* n = (Name*) malloc(sizeof(Name*));
n->s = str;
return n;
}
//--------------------------------------------------------------------------
#endif
main.c:
#include <stdlib.h> // malloc
#include <stdio.h> // printf
#include <assert.h> // assert
#ifdef __cplusplus
#else // compiling in C.
int main ()
{
List* lst = create();
char* names[ ] = { "Giorikas", "Kostikas", "Foo", "Bar", "Gosho", "Pesho" };
char* name;
int i = 0;
int size = 6;
for (i; i < size; ++i)
{
push_back(lst, (Link*)(make_name(names[i])));
name = ((Name*)(lst->last))->s;
printf("Name: %s \n", name);
}
destroy(lst);
getchar();
return 0;
}
#endif
使用调试器,我打印了名称,在函数clear() 中,第一次尝试释放链接时,我收到两个警告,最后:
_CrtIsValidHeapPointer(pUserData)
注意:经过一番研究,我了解到:“您不会在重写时立即收到堆损坏,而是 在下一次堆检查时,这将在任何下一次内存分配/释放。”。因此,clear() 中发生的可能是触发错误的堆检查。
这个堆损坏发生在哪里?
【问题讨论】:
-
完全不相关,但名称更有意义的是
succ/pred或next/prev,而不是succ/prev。 -
与您的问题无关,但不要将函数定义(实现)放在头文件中。相反,只需将函数的声明放在头文件中,然后将定义放在单独的源文件中,然后使用该文件进行构建。
-
@BLUEPIXY 你是说演员吗?
-
@BLUEPIXY 我将
Name理解为基类Link的“派生”类 -
@Someprogrammerdude 啊,我误解了
Link和Link*。我似乎没有足够的睡眠。对不起 Ziezi 和一些程序员老兄。
标签: c data-structures heap-memory