Cod*_*lus 3 c generics malloc pointers linked-list
我有一个通用的链表,其中包含void*类型的数据我试图使用struct employee填充我的列表,最终我想破坏对象struct employee.
考虑这个通用的链表头文件(我用char*类型测试过它):
struct accListNode //the nodes of a linked-list for any data type
{
void *data; //generic pointer to any data type
struct accListNode *next; //the next node in the list
};
struct accList //a linked-list consisting of accListNodes
{
struct accListNode *head;
struct accListNode *tail;
int size;
};
void accList_allocate(struct accList *theList); //allocate the accList and set to NULL
void appendToEnd(void *data, struct accList *theList); //append data to the end of the accList
void removeData(void *data, struct accList *theList); //removes data from accList
--------------------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
考虑员工结构
struct employee
{
char name[20];
float wageRate;
}
Run Code Online (Sandbox Code Playgroud)
现在考虑将从main()调用的示例测试用例:
void test2()
{
struct accList secondList;
struct employee *emp = Malloc(sizeof(struct employee));
emp->name = "Dan";
emp->wageRate =.5;
struct employee *emp2 = Malloc(sizeof(struct employee));
emp2->name = "Stan";
emp2->wageRate = .3;
accList_allocate(&secondList);
appendToEnd(emp, &secondList);
appendToEnd(emp2, &secondList);
printf("Employee: %s\n", ((struct employee*)secondList.head->data)->name); //cast to type struct employee
printf("Employee2: %s\n", ((struct employee*)secondList.tail->data)->name);
}
Run Code Online (Sandbox Code Playgroud)
为什么我在下面发布的答案解决了我的问题?我相信它与指针和内存分配有关.我使用的函数Malloc()是一个自定义malloc,它检查返回的NULL.
以下是我的整个通用链表实现的链接:https://codereview.stackexchange.com/questions/13007/c-linked-list-implementation
问题是这个accList_allocate()和你使用它.
struct accList secondList;
accList_allocate(&secondList);
Run Code Online (Sandbox Code Playgroud)
在原始test2()中,secondList是堆栈上的内存.&secondList是指向该内存的指针.当你调用accList_allocate()时,指针的副本将指向堆栈内存.然后,Malloc()返回一块内存并将其分配给指针的副本,而不是原始的secondList.
退出后,secondList仍指向堆栈上未初始化的内存,因此对appendToEnd()的调用失败.
除了secondList恰好没有垃圾之外,答案也是如此.可能是偶然的,可能是通过编译器的设计.无论哪种方式,它都不是你应该依赖的东西.
或者:
struct accList *secondList = NULL;
accList_allocate(&secondList);
Run Code Online (Sandbox Code Playgroud)
并更改accList_allocate()
accList_allocate(struct accList **theList) {
*theList = Malloc(sizeof(struct accList));
(*theList)->head = NULL;
(*theList)->tail = NULL;
(*theList)->size = 0;
}
Run Code Online (Sandbox Code Playgroud)
要么
struct accList secondList;
accList_initialise(secondList);
Run Code Online (Sandbox Code Playgroud)
随着accList_allocate()更改为accList_initialise(),因为它没有分配
accList_initialise(struct accList *theList) {
theList->head = NULL;
theList->tail = NULL;
theList->size = 0;
}
Run Code Online (Sandbox Code Playgroud)