贝娄是相关代码:
typedef struct Node_t {
ListElement data;
struct Node_t* next;
} Node;
struct List_t {
Node* head;
Node* tail;
Node* current;
int size;
CopyListElement copyF;
FreeListElement freeF;
};
static ListResult initializeNode(List list, ListElement element, Node* newNode){
printf("\nEntered initializeNode\n");
if ((list == NULL) || (element == NULL)) return LIST_NULL_ARGUMENT;
newNode = malloc(sizeof(Node));
if (newNode == NULL) return LIST_OUT_OF_MEMORY;
printf("\nWithin initializeNode, before copyF\n");
ListElement newElement = list->copyF(element);
printf("\nWithin initializeNode, after copyF\n");
if (newElement == NULL) return LIST_OUT_OF_MEMORY;
newNode->data = newElement;
printf("\nLast line within initializeNode\n");
return LIST_SUCCESS;
}
List listCreate(CopyListElement copyElement, FreeListElement freeElement){
//Check if there is a NULL argument.
if ((copyElement == NULL) || (freeElement == NULL)) return NULL;
//Check wether there is enough memory.
List newList = malloc(sizeof(List));
if (newList == NULL) return NULL;
//Initialize an empty List.
newList->head = NULL;
newList->tail = NULL;
newList->size = 0;
newList->current = NULL;
newList->copyF = copyElement;
newList->freeF = freeElement;
return newList;
}
ListResult listInsertFirst(List list, ListElement element){
printf("\nEntered listInsertFirst\n");
Node* newNode;
ListResult result = initializeNode(list, element, newNode);
printf("\n Node was initialized\n");
if (result != LIST_SUCCESS) {
return result;
}
printf("\nEntering logistic works within listInsertFirst\n");
//Finish logistic work within the Node.
newNode->next = list->head;
list->head = newNode;
list->size++;
printf("\nElement was inserted successfully\n");
printf("\nCheck list->CopyF within listInsertFirst\n");
list->copyF(element);
printf("\nCheck list->CopyF within listInsertFirst: PASSED\n");
return LIST_SUCCESS;
}
在我正在尝试的主要功能中:
List list = listCreate(©Int, &freeInt);
ListResult result;
int el=2;
//ListElement e1;
//ListElement e2;
result = listInsertFirst(list,&el);
printf("\nresult = %d\n", result);
result = listInsertFirst(list,&el);
printf("\nresult = %d\n", result);
编译并运行后,我得到:
输入listInsertFirst
输入initializeNode
在initializeNode中,在copyF
之前在initializeNode中,在copyF
之后initializeNode
中的最后一行节点已初始化
在listInsertFirst中输入后勤工作
元素已成功插入
检查列表 - > listInsertFirst中的CopyF分段错误:11
由于某种原因,指针[to function] list-> copyF被破坏[我认为]。
答案 0 :(得分:1)
我假设这是基于标签的C代码,而不是C ++。鉴于你有混合的数据定义和实际的代码语句,我不希望在C中工作,我不是百分之百确定它是真正的C,在这种情况下我可能错误的是下面的错误。 / p>
首先,initializeNode()
的接口没有达到您想要的效果。你可能想要:
static ListResult initializeNode(List list, ListElement element, Node** newNodep)
{
Node *newNode = malloc(sizeof(Node));
if (newNode == NULL) return LIST_OUT_OF_MEMORY;
ListElement newElement = list->copyF(element);
if (newElement == NULL) return LIST_OUT_OF_MEMORY;
newNode->data = newElement;
*newNodep = newNode;
return LIST_SUCCESS;
}
这样您创建的节点就会被传回。
我不知道CopyInt()
的作用是什么,但是如果真的是函数遇到总线错误,则initializeNode()
的错误不是你的问题。但是,在报告崩溃之前,您可能没有看到所有printfs的输出。
如果CopyInt()
做了我期望的事情,那就是:
ListElement CopyInt(int *val)
{
ListElement *e = malloc(sizeof(ListElement));
if (e)
e->val = *val;
return e;
}
如果你搞乱了库函数malloc()
维护的数据结构,那么你在这里获得第二次总线错误的唯一方法就是这样。不幸的是,对于这个理论,我没有看到比这里的内存泄漏更糟糕的事情。
答案 1 :(得分:0)
我猜这个实际导致崩溃的错误是这一行:
newNode->next = list->head;
就像@Arlie Stephens所说的那样 - initializeNode
的代码没有做任何事情,因为指针是按值传递的,实际的指针仍指向垃圾。因此,当你执行newNode->next = list->head;
时,你基本上是在写一个未知地址,而且很可能会出现分段错误。
为什么它只发生在第二次通话?不知道,这是未定义的行为。
疯狂的想法 - 有可能newNode-> next被初始化为copyF的地址并尝试写入它会导致你损坏copyF ...尝试打印newNode-> next的地址和copyF的地址