I dont have explansion for what happening to my code, i have a generic linked list
and it worked like a charm just yesterday, i didn’t change it in any way, but somehow
now when the getters and setters of the list try to reach the fields of the list or it’s nodes i getting those SIGSEGV faults and my code terminating, that’s the relevant part of my list.c file :
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;
}
i also have that typedef in the list.h file which included in the ilst.c file:
typedef struct LinkedList* List;
after debugging for hours i noticed that the head and tail dont get NULL value when the list created, they still have some address instead of zeros, it also happens in the create node and other uses of this list, why is it? my heap is corrupted? why it doesn’t assign null to those fields as it should?! anyway plz remember it worked well and i have no idea what changed it.. thanks!
edit:
this is the AddNode function in my node.c file:
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;
}
here on the first call to AddNode, when the list is empty and I’m adding the first element
it jumps the if of empty linked list and go for else that come after that, it shouldn’t. what can make this happen in my app code?
edit 2:
ok this is the only struct allocation before i use the list:
struct Server_t
{
List UsersList;
};
Result CreateServer(Server thisServer)
{
if (thisServer = (Server)malloc(sizeof(struct Server_t)))
{
thisServer->UsersList = CreateLinkedList();
return Success;
}
return Failed;
}
and the main call it that way:
Server mainFacebookServer;
CreateServer(mainFacebookServer);
Result is enum, and Server is a pointer to that struct.
edit 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;
}
and the setters are:
void SetNext(Node node, Node toSet)
{
node->m_next = toSet;
}
void SetPrev(Node node, Node toSet)
{
node->m_prev = toSet;
}
This code does not do what you think it does:
If you’re going to return the
Serverby value, you must pass a pointer into the function:The original code both leaks memory and invites segmentation faults because the
struct Server_tvalue used afterCreateServer()returns has not been initialized.Working Code
The following code works under
valgrind(there’s system-allocated memory still reachable, but nothing leaked or abused). The problem was indeed in theCreateServer()function, as diagnosed earlier.When compiled with the XCode 4.x GCC/LLVM on MacOS X 10.7.2 and run with Valgrind 3.7.0, I get:
When run with
--show-reachable=yes, the extra reports are similar to this one (from a different run, as you can see:Not exciting – except for the amount of background work going on – and definitely an issue (or not) with the system rather than the code in the program.