我没有解释我的代码发生了什么,我有一个通用的链表 它就像昨天的魅力一样,我没有以任何方式改变它,但不知何故 现在,当列表的getter和setter尝试到达列表的字段或它的节点时,我收到SIGSEGV错误并且我的代码终止,这是我的list.c文件的相关部分:
struct LinkedList
{
Node m_head;
Node m_tail;
int m_numOfElements;
};
List CreateLinkedList()
{
List list = (List)malloc(sizeof(struct LinkedList));
if (list == NULL)
{
printf("memory alloc failed\n");
return NULL;
}
list->m_head = NULL;
list->m_tail = NULL;
list->m_numOfElements = 0;
return list;
}
我在list.h文件中也有typedef,其中包含ilst.c文件:
typedef struct LinkedList* List;
经过几个小时的调试后,我注意到头部和尾部在创建列表时没有得到NULL值,它们仍然有一些地址而不是零,它也发生在创建节点和此列表的其他用途中,为什么呢?我的堆已损坏?为什么它没有为那些字段分配null呢?无论如何,请记住它运作良好,我不知道是什么改变了它...谢谢!
编辑:
这是我的node.c文件中的AddNode函数:
int AddNode(List list, Element data)
{
Node newNode;
//there is no linked list to add the element to
if(list == NULL)
return -1;
newNode = CreateNewNode(data);
if(newNode == NULL)
{
printf("Failed allocating memory\n");
return 1;
}
//Empty Linked List
if (list->m_head == NULL)
{
list->m_tail = list->m_head = newNode;
}
else
{
SetNext(list->m_tail,newNode);
SetPrev(newNode, list->m_tail);
list->m_tail = newNode;
}
//increase num of elements
list->m_numOfElements++;
return 1;
}
这里是第一次调用AddNode,当列表为空时我正在添加第一个元素 它会跳过空链表的if,然后转到其后的那个,它不应该。什么可以在我的应用程序代码中实现这一点?
编辑2:
确定这是我使用列表之前唯一的结构分配:
struct Server_t
{
List UsersList;
};
Result CreateServer(Server thisServer)
{
if (thisServer = (Server)malloc(sizeof(struct Server_t)))
{
thisServer->UsersList = CreateLinkedList();
return Success;
}
return Failed;
}
主要称之为:
Server mainFacebookServer;
CreateServer(mainFacebookServer);
结果是枚举,Server是指向该结构的指针。
编辑3:
Node CreateNewNode(Element data)
{
Node newNode = (Node)malloc(sizeof(struct NODE));
newNode->m_next = NULL;
newNode->m_prev = NULL;
newNode->m_data = data;
return newNode;
}
和制定者是:
void SetNext(Node node, Node toSet)
{
node->m_next = toSet;
}
void SetPrev(Node node, Node toSet)
{
node->m_prev = toSet;
}
答案 0 :(得分:0)
此代码不符合您的预期:
Result CreateServer(Server thisServer)
{
if (thisServer = (Server)malloc(sizeof(struct Server_t)))
{
thisServer->UsersList = CreateLinkedList();
return Success;
}
return Failed;
}
如果您要按值返回Server
,则必须将指针传递给函数:
Result CreateServer(Server *thisServer)
{
if (*thisServer = (Server)malloc(sizeof(struct Server_t)))
{
(*thisServer)->UsersList = CreateLinkedList();
return Success;
}
return Failed;
}
原始代码泄漏内存并引发分段错误,因为struct Server_t
返回后使用的CreateServer()
值尚未初始化。
以下代码在valgrind
下工作(系统分配的内存仍然可以访问,但没有任何泄漏或滥用)。问题确实存在于CreateServer()
函数中,如前所述。
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
typedef int Element;
typedef struct Node *Node;
struct Node
{
Node m_prev;
Node m_next;
Element m_data;
};
struct LinkedList
{
Node m_head;
Node m_tail;
int m_numOfElements;
};
typedef struct LinkedList *List;
struct Server_t
{
List UsersList;
};
typedef struct Server_t *Server;
typedef enum Result { Failed, Success } Result;
extern Result CreateServer(Server *thisServer);
extern Result AddNode(List list, Element data);
extern void SetPrev(Node node, Node toSet);
extern void SetNext(Node node, Node toSet);
extern Node CreateNewNode(Element data);
extern List CreateLinkedList(void);
extern void DestroyServer(Server server);
extern void DestroyLinkedList(List list);
List CreateLinkedList(void)
{
List list = (List)malloc(sizeof(struct LinkedList));
if (list == NULL)
{
printf("memory alloc failed\n");
return NULL;
}
list->m_head = NULL;
list->m_tail = NULL;
list->m_numOfElements = 0;
return list;
}
Node CreateNewNode(Element data)
{
Node newNode = (Node)malloc(sizeof(struct Node));
newNode->m_next = NULL;
newNode->m_prev = NULL;
newNode->m_data = data;
return newNode;
}
void SetNext(Node node, Node toSet)
{
node->m_next = toSet;
}
void SetPrev(Node node, Node toSet)
{
node->m_prev = toSet;
}
Result AddNode(List list, Element data)
{
Node newNode;
//there is no linked list to add the element to
if (list == NULL)
return Failed;
newNode = CreateNewNode(data);
if (newNode == NULL)
{
printf("Failed allocating memory\n");
return Failed;
}
//Empty Linked List
if (list->m_head == NULL)
{
list->m_tail = list->m_head = newNode;
}
else
{
SetNext(list->m_tail,newNode);
SetPrev(newNode, list->m_tail);
list->m_tail = newNode;
}
//increase num of elements
list->m_numOfElements++;
return Success;
}
Result CreateServer(Server *thisServer)
{
if ((*thisServer = (Server)malloc(sizeof(struct Server_t))) != 0)
{
if (((*thisServer)->UsersList = CreateLinkedList()) != 0)
return Success;
}
return Failed;
}
void DestroyLinkedList(List list)
{
Node node;
Node next;
assert(list != 0);
for (node = list->m_head; node != 0; node = next)
{
next = node->m_next;
free(node);
}
free(list);
}
void DestroyServer(Server server)
{
assert(server != 0);
assert(server->UsersList != 0);
DestroyLinkedList(server->UsersList);
free(server);
}
int main(void)
{
Server mainFacebookServer;
if (CreateServer(&mainFacebookServer) == Success)
{
if (AddNode(mainFacebookServer->UsersList, 1) == Success)
{
/* Use new user list */
}
DestroyServer(mainFacebookServer);
}
return(0);
}
在MacOS X 10.7.2上使用XCode 4.x GCC / LLVM编译并使用Valgrind 3.7.0运行时,我得到:
$ /usr/bin/gcc -O3 -g -std=c99 -Wall -Wextra -Werror xxx.c -o xxx
$ valgrind --leak-check=full xxx
==51464== Memcheck, a memory error detector
==51464== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==51464== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==51464== Command: xxx
==51464==
==51464==
==51464== HEAP SUMMARY:
==51464== in use at exit: 2,095 bytes in 32 blocks
==51464== total heap usage: 35 allocs, 3 frees, 2,151 bytes allocated
==51464==
==51464== LEAK SUMMARY:
==51464== definitely lost: 0 bytes in 0 blocks
==51464== indirectly lost: 0 bytes in 0 blocks
==51464== possibly lost: 0 bytes in 0 blocks
==51464== still reachable: 2,095 bytes in 32 blocks
==51464== suppressed: 0 bytes in 0 blocks
==51464== Reachable blocks (those to which a pointer was found) are not shown.
==51464== To see them, rerun with: --leak-check=full --show-reachable=yes
==51464==
==51464== For counts of detected and suppressed errors, rerun with: -v
==51464== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)
$
使用--show-reachable=yes
运行时,额外的报告与此类似(来自不同的运行,如您所见:
==51375== 616 bytes in 7 blocks are still reachable in loss record 8 of 8
==51375== at 0xC3F3: calloc (vg_replace_malloc.c:569)
==51375== by 0x312AAA: _xpc_calloc (in /usr/lib/system/libxpc.dylib)
==51375== by 0x313384: _xpc_base_create (in /usr/lib/system/libxpc.dylib)
==51375== by 0x319CE2: xpc_string_create (in /usr/lib/system/libxpc.dylib)
==51375== by 0x318EF5: xpc_dictionary_set_string (in /usr/lib/system/libxpc.dylib)
==51375== by 0x31AF49: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==51375== by 0x18E7D: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==51375== by 0x7FFF5FC0FD19: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==51375== by 0x7FFF5FC0FA65: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==51375== by 0x7FFF5FC0D257: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==51375== by 0x7FFF5FC0D1F0: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==51375== by 0x7FFF5FC0E02A: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==51375==
不令人兴奋 - 除了正在进行的后台工作量 - 并且肯定是系统的问题(或不是),而不是程序中的代码。