|
From: Gerald G. <ger...@ya...> - 2003-12-11 14:43:37
|
I've been using valgrind now for quite some time now,
I guess I have improved my coding with it. For a
couple
of days now I've been trying to trace read violation.
The code is quite long but I'll just the describe some
of the areas here.
The code below is a node extraction below for a doubly
linked
list. it handles the start and end node condition and
the last
part handles the somewhere-in-the-middle condition.
The sections
are identical in procedures except for the position to
operate on,
the node is deleted from the list at the end of each
condition.
Valgrind however reports a misread on the last part of
the function.
Its reporting several places, but its all rooted on
this single
function. Valgrind doesnt report anything when the
function is operating
on the start and end of the list. dllist.c corresponds
to the last call
to free() at the bottom. Is there anything wrong with
my code or is this
a known bug in valgrind. I'd appreciate any feedback
because I've been
trying to solve this for a couple of days now. Thanks
a lot.
Gerald R. Generoso
Command line options used: -v
Operating system: Redhat 9
GCC version: 3.2.2
==4760== Invalid read of size 4
==4760== at 0x8049736: dllist_searchList
(dllist.c:969)
==4760== by 0x8049CB5: main (xsearch.c:68)
==4760== by 0x40245916: __libc_start_main (in
/lib/libc-2.3.2.so)
==4760== by 0x804854C: ??? (start.S:81)
==4760== Address 0x411A43D0 is 12 bytes inside a
block of size 20 free'd
==4760== at 0x40029961: free
(vg_replace_malloc.c:231)
==4760== by 0x80490F4: dllist_extractNode
(dllist.c:576)
==4760== by 0x8049910: dllist_srta_extractNode
(dllist.c:1095)
==4760== by 0x8049706: dllist_searchList
(dllist.c:955)
/*----------------------------------------------------------------------------*/
int dllist_extractNode(dllist **listNode,
dllist **loadPtr,
fcn **statusObj,
char *fileName,
int lineNumber)
{
dllist *nodeObj = (*listNode);
dllist *tmp_load = (*loadPtr);
dllist *tmpNode = NULL;
fcn *status = (*statusObj);
errno = 0;
if(!nodeObj)
{
fcn_writeMsg(&status,
NULL_PTR,
"dllist_extractNode",
"listNode"IS_NULL,
fileName,
lineNumber);
return FAILED;
}
/*store node here before removing from the list*/
if(tmp_load)
{
if((tmp_load->loadObj =
memmove(tmp_load->loadObj,
nodeObj->loadObj,
nodeObj->size_loadObj)) ==
NULL)
{
fcn_writeMsg(&status,
errno,
"dllist_extractNode",
strerror(errno),
fileName,
lineNumber);
return FAILED;
}
tmp_load->tagObj = nodeObj->tagObj;
tmp_load->size_loadObj = nodeObj->size_loadObj;
(*loadPtr) = tmp_load;
}
/*the start of list condition*/
if(nodeObj->prevNode == NULL)
{
tmpNode = nodeObj->nextNode;
if(nodeObj->loadObj)
{
free(nodeObj->loadObj);
nodeObj->loadObj = NULL;
}
free(nodeObj);
nodeObj = NULL;
if(tmpNode)
{
tmpNode->prevNode = NULL;
}
(*listNode) = tmpNode;
return SUCCESS;
}
/*the end of list condition*/
if(nodeObj->nextNode == NULL)
{
tmpNode = nodeObj->prevNode;
if(nodeObj->loadObj)
{
free(nodeObj->loadObj);
nodeObj->loadObj = NULL;
}
free(nodeObj);
nodeObj = NULL;
if(tmpNode)
{
tmpNode->nextNode = NULL;
}
(*listNode) = tmpNode;
return SUCCESS;
}
/*somewhere in the middle condition*/
nodeObj->prevNode->nextNode = nodeObj->nextNode;
nodeObj->nextNode->prevNode =
nodeObj->prevNode;
if(nodeObj->loadObj)
{
free(nodeObj->loadObj);
nodeObj->loadObj = NULL;
}
/*valgrind reports a misread here!*/
free(nodeObj);
nodeObj = NULL;
return SUCCESS;
}/*End of dllist_extractNode*/
__________________________________
Do you Yahoo!?
New Yahoo! Photos - easier uploading and sharing.
http://photos.yahoo.com/
|
|
From: Jorrit T. <Jor...@uz...> - 2003-12-11 14:58:54
|
Gerald Generoso wrote:
>==4760== Invalid read of size 4
>==4760== at 0x8049736: dllist_searchList
>(dllist.c:969)
>
>
>
>/*----------------------------------------------------------------------------*/
>int dllist_extractNode(dllist **listNode,
> dllist **loadPtr,
> fcn **statusObj,
> char *fileName,
> int lineNumber)
>{
>
>
Hmm. valgrind complains about dllist_searchList. However you show
us the source of dllist_extractNode. Why do you conclude that the
bug has to be in dllist_extractNode in order to trigger in
dllist_extractNode?
Greetings,
|
|
From: Gerald G. <ger...@ya...> - 2003-12-11 15:20:41
|
>/*----------------------------------------------------------------------------*/
> >int dllist_extractNode(dllist **listNode,
> > dllist **loadPtr,
> > fcn **statusObj,
> > char *fileName,
> > int lineNumber)
> >{
> >
> >
> Hmm. valgrind complains about dllist_searchList.
> However you show
> us the source of dllist_extractNode. Why do you
> conclude that the
> bug has to be in dllist_extractNode in order to
> trigger in
> dllist_extractNode?
I guess I should post the declarations for the other
functions and some explanation :)
The function dllist_searchList accepts a pointer to
a function as its last parameter. The other function
dllist_srta_extractNode acts as wrapper for
dllist_extractNode, dllist_srta_extractNode is the
one used as a parameter for dllist_searchList.
dllist_searchList merely acts as a traversal mechanism
which depends on other functions for the direction
of traversal and comparison. the direction and
comparison in this case is handled by
dllist_srta_extractNode, and finally if the comparison
part finds a match dllist_extractNode is called in to
do the extraction part. I hope this bit helps.
int dllist_searchList(dllist **listNode,
void *searchKey,
dllist **loadPtr,
fcn **statusObj,
char *fileName,
int lineNumber,
int (*dllist_function)(dllist
**listNode,
void
*searchKey,
dllist
**loadPtr,
search_ctrl
*ctrlObj,
fcn
**statusObj,
char
*fileName,
int
lineNumber))
/*****************************************************/
int dllist_srta_extractNode(dllist **listNode,
void *searchKey,
dllist **loadPtr,
search_ctrl *ctrlObj,
fcn **statusObj,
char *fileName,
int lineNumber)
__________________________________
Do you Yahoo!?
New Yahoo! Photos - easier uploading and sharing.
http://photos.yahoo.com/
|
|
From: Dan K. <da...@ke...> - 2003-12-11 15:29:39
|
Gerald Generoso wrote: > The code below is a node extraction below for a doubly > linked list. Your code is awful complicated. Here's a simpler example from http://www.cs.trinity.edu/~bmassing/Classes/CS1321_2001spring/SamplePrograms/dll-1.h // Delete the specified link. // Pre: *pos is not the sentinel link. // Post: link *pos has been removed from the list. // returns pointer to link following *pos. link * erase(link *const pos) { link * n = pos; // or we could have passed "pos" by value link * answer = n->next; // Change the surrounding links' pointers. n->prev->next = n->next; n->next->prev = n->prev; // Change new link's pointers (not actually necessary). n->prev = 0; n->next = 0; delete n; return answer; } They finesse the start and end of list conditions by using a dummy node. Here's another example from http://cs-people.bu.edu/jalon/cs113-01/dlistlab/dlist.html which is slightly more complicated, but doesn't need a dummy node: if (currP->getPrev() == NULL) { /* Remove from beginning */ /* Fix beginning pointer. */ head = currP->getNext(); } else if(currP->getNext() == NULL) { /* Remove from end */ currP->getPrev()->setNext(NULL); } else { /* Remove from middle */ /* * Fix previous node's next to * skip over the removed node. */ currP->getPrev()->setNext(currP->getNext()); /* * Fix next node's prev to * skip over the removed node. */ currP->getNext()->setPrev(currP->getPrev()); } In other words, you should probably throw out your code and start over more simply... - Dan |