*glibc detected double free or corruption() * message! - c

The following deleteNode function when I run the program gets these:
* glibc detected free(): invalid next size (normal): 0x000000000103dd90 **
Even i make the ' free(here); ' a comment,i get the above message.
I dont think that the other 'free' calls provokes a problem like that. But I cant see why this would be wrong. :/
struct List *deleteNode(int Code,int i,char* Number)
{
struct List *here;
here=Head;
for (here; here!=Tail; here=here->next)
{
if ( (here->number==Number) && (here->code==Code) )//found node on the List
{
if (here->previous==Head) //delete from beginning
{
Head=here->next;
here->next->previous=Head;
}
else if (here->next==Tail) //delete from the end
{
here->previous->next=Tail;
Tail=here->previous;
}
else //delete from the middle of the list
{
here->previous->next=here->next;
here->next->previous=here->previous;
}
break;
}
}
free (here);
}
EDIT:
if i used and understand valgring well then the problem is on my main function.
i have also there some 'free' but i changed deleteNode before this message so i thought that the problem was on the deleteNode function.
Now,there is no free() invalid next size.... but unfortunately this:
glibc detected * : double free or corruption (out): 0x00007fff1aae9ae0 *
:(
A part of the main:
FILE *File;
if ( ( File=fopen("File.txt","r")) !=NULL )
{
int li = 0;
char *lin = (char *) malloc(MAX_LINE * sizeof(char));
while(fgets(lin, MAX_LINE, eventFile) != NULL)
{
token = linetok(lin, " ");
if(token != NULL)
{
int i,code,nodeID;
char *number;
char *event;
for(i = 0; token[i] != NULL; i += 1)
{
code=atoi(token[0]);
strcpy(event,token[1]);
nodeID=atoi(token[2]);
strcpy(number,token[3]) ;
int i;
if (!strcmp(event,"add"))
{
add_to_List(code,i,number);
}
else if(!strcmp(event,"delete"))
{
deleteNode(eventNo,i,number);
}
free(event);
free(phoneNumber);
}
free(token);
}
else
{
printf("Error reading line %s\n", lin);
exit(1);
}
}
}
else
{
printf("Error opening file with the events.\nEXIT!");
exit(0);
}
debugging it...
multiple definition of main'
pro:(.text+0xce0): first defined here
/usr/lib/gcc/x86_64-linux-gnu/4.4.1/crtend.o:(.dtors+0x0): multiple definition ofDTOR_END'
pro:(.dtors+0x8): first defined here
/usr/bin/ld: warning: Cannot create .eh_frame_hdr section, --eh-frame-hdr ignored.
/usr/bin/ld: error in pro1(.eh_frame); no .eh_frame_hdr table will be created.
collect2: ld returned 1 exit status

"Invalid next size" means that glibc has detected corruption in your memory arena.
You have overwritten valuable accounting information that's stored in between your allocated blocks.
With each block that malloc gives you, there is some accounting information stored close by. When you overwrite this information by, for example, writing 128 characters to a 20-character buffer, glibc may detect this the next time you try to free (or possibly allocate) some memory.
You need to find the root cause of this problem - it's not the free itself, that's just where the problem is being detected. Somewhere, some of your code is trashing memory and a memory analysis tool like valgrind will be invaluable here.

If the node is not found in the list, you will free the Tail node at the end of the function, without updating Tail to point to anything valid again.
Further using the list and the now deallocated Tail can easily result in memory corruption that might later be detected by glibc with a message like the one you got.
Also note that in (here->number==Number) you are comparing two pointers, not the values those pointers point to. I'm not sure if that's what you want.

Related

Clear the last element from a linked list

I am working on a C program which has a linked list. I need to remove the last element from the linked list and it is mostly working except when it hits particular part of my code it then has a segmentation fault.
The code that I have is as follows:
int clearOutboundLegFromList(callLogSearchOutboundStruct ** outboundLeg, int dataCol, int rowTargets)
{
//callLogSearchOutboundStruct *currentStruct = *outboundLeg;
//callLogSearchOutboundStruct *temp;
if (*outboundLeg == NULL)
{
return 0;
}
SL_DebugAll(DBG_ALWAYS, "DEBUG: Clearing outbound legs: DataCol: %i RowTargets: %i",
dataCol, rowTargets);
callLogSearchOutboundStruct *legToRemove = NULL;
callLogSearchOutboundStruct *last = NULL;
legToRemove = *outboundLeg;
while (legToRemove->nextLeg != NULL)
{
last = legToRemove;
legToRemove = legToRemove->nextLeg;
}
if (legToRemove->target != NULL)
{
free(legToRemove->target);
legToRemove->target = NULL;
}
if (legToRemove->cleardownCause)
{
free(legToRemove->cleardownCause);
legToRemove->cleardownCause = NULL;
}
free(legToRemove);
if (last != NULL)
{
last->nextLeg = NULL;
}
legToRemove = NULL;
}
It crashes on the line of free(legToRemove->target);.
In the core dump I have the following:
Program terminated with signal 11, Segmentation fault.
#0 0x00b01336 in _int_free () from /lib/libc.so.6
Missing separate debuginfos, use: debuginfo-install cyrus-sasl-lib-2.1.23-13.el6_3.1.i686 glibc-2.12-1.132.el6_5.2.i686 keyutils-libs-1.4-4.el6.i686 krb5-libs-1.10.3-15.el6_5.1.i686 libcom_err-1.41.12-18.el6.i686 libcurl-7.19.7-37.el6_5.3.i686 libidn-1.18-2.el6.i686 libselinux-2.0.94-5.3.el6_4.1.i686 libssh2-1.4.2-1.el6.i686 mysql-libs-5.1.73-3.el6_5.i686 nspr-4.9.2-1.el6.i686 nss-3.14.0.0-12.el6.i686 nss-softokn-freebl-3.12.9-11.el6.i686 nss-util-3.14.0.0-2.el6.i686 openldap-2.4.23-31.el6.i686 openssl-1.0.1e-16.el6_5.14.i686 zlib-1.2.3-29.el6.i686
(gdb) bt
#0 0x00b01336 in _int_free () from /lib/libc.so.6
#1 0x0805cd0b in clearOutboundLegFromList (outboundLeg=0xb5de7984, dataCol=9, rowTargets=11) at performreport.c:6731
#2 0x08058f33 in processDrilldownData (reportParameterArray=..., csvFile=0x8e3fc78, HandleDB=0xbfca7a14, resultReport=0x8e457a8,
If I print from the core dump legToRemove->target gdb outputs the following:
$1 = 0x99235d8 ""
Now that looks like its a properly allocated memory space, it just contains an empty string so I don't understand why this would cause a segfault.
You don't show how your struct looks like or how you add legs to your linked list, but you have an error in your removal function that occurs if you remove the last node: In that case, your list head should be set to NULL.
This special case is the reason to pass the list head as pointer to pointer to leg: The function must be able to update the head when the first node is removed. If you don't do that, the value of the head in the calling function will be the same and it will refer to memory that you have just freed. It is illegal to access such memory.
So, an updated version of your code could look like this:
void clearOutboundLegFromList(callLogSearchOutboundStruct **outboundLeg)
{
callLogSearchOutboundStruct *last = NULL;
legToRemove = *outboundLeg;
if (legToRemove == NULL) return;
while (legToRemove->nextLeg) {
last = legToRemove;
legToRemove = legToRemove->nextLeg;
}
free(legToRemove->target);
free(legToRemove->cleardownCause);
free(legToRemove);
if (last) {
last->nextLeg = NULL;
} else {
*outboundLeg = NULL;
}
}
You need the explicit assignment at the end, because once you have initialised legToRemove, you are operating only with that local pointer.
If you are feeling more confident with double indirections via pointers to pointers, you could iterate to the end without local variabes:
void clearOutboundLegFromList(callLogSearchOutboundStruct **outboundLeg)
{
if (*outboundLeg == NULL) return;
while (*outboundLeg) {
outboundLeg = &(*outboundLeg)->nextLeg;
}
free((*outboundLeg)->target);
free((*outboundLeg)->cleardownCause);
free(*outboundLeg);
*outboundLeg = NULL;
}
This will update the head pointer automatically when the first element is removed. The idea here ist that outboundLeg points to the head node at the beginning and to the previous node's nextLeg pointer on subsequent iterations. The additional indirection via (*outboundLeg) is more or less the same as accessing a node via the nextLeg member, except for the first node, in which you access the pointer through the head node pointer.
(Distraction: Your code is overly cautious when freeing the member pointers. It is legal to free a null pointer; this doesn't do anything, but means that you don't have to check for NULL in client code. Such a check might still be good practice, because many functions won't take null pointers. Setting the member pointers to NULL is a good idea if these pointers were still around for some time. But you are going to free the containing struct anyway soon. Setting the pointers to NULL is a bit like cleaning the bathroom just before you tear down the house. Setting legToRemove to NULL at the end of the function doesn't do anything: The pointer will go out of scope anyway. That's just an aside and retionale for my shorter code. Your checks aren't wrong and it is better to be cautious.)

Memory fault - c

I do not know why I get Memory fault (core dumped) when I run this code
if (flg == 4) // PIPE
{
char **cmds;
char ***cmdarg;
int j=0;
cmds = split_str(cmd, "|");
for (i = 0; args[i] != NULL; i++)
{
if (strcmp(args[i], "|") == 1)
{
cmdarg[j][i]=args[i];
}
else
{
cmdarg[j][i+1] = NULL;
j++;
}
printf("%s\n",cmdarg[j][i]);
}
}
I am not so expert with pointers and arrays
cmdarg is not initialized. And I'm sure that GCC, when invoked as gcc -Wall -g, would have warned you about that.
You could keep its length, e.g.
int cmdarglen = 0;
Then initialize it to some suitable default size:
#define INITIAL_CMDARG_SIZE 10
cmdarg = calloc(INITIAL_CMDARG_SIZE, sizeof(*cmdarg));
if (!cmdarg) { perror("calloc cmdarg initial"); exit (EXIT_FAILURE); );
cmdarglen = INITIAL_CMDARG_SIZE;
then grow it when needed, e.g.
if (j >= cmdarglen) {
int newcmdarglen = 5*j/4+10;
char***newcmdarg = calloc(newcmdarglen, sizeof(*cmdarg));
if (!newcmdarg)
{ perror("calloc growing cmdarg"); exit(EXIT_FAILURE); };
memcpy (newcmdarg, cmdarg, sizeof(*cmdarg)*j);
free (cmdarg);
cmdarg = newcmdarg;
}
to be inserted appropriately inside your for loop. Of course, you probably need to initialize each element of cmdarg (by allocating them individually).
Don't forget to free(cmdarg) later.
At last, learn how to use the gdb debugger and valgrind memory leak detector.
You never initialize the cmdarg variable in you code. It will have an unspecified value, so when you dereference it, there is undefined behavior. In your case, this manifest by a segmentation fault.
I don't know what your code is trying to do, but what I can see is that you are reffering to an uninitialized variable 'cmdarg'.Another adivce: when possible (and I think that nearly always it is possible) try to avoid three levels of indirections (***).

Whether code is read from top to bottom

I am creating a program in c which is based on a linked list, where every node (of struct) holds an integer and a pointer to the next node.
I use dynamic allocation (malloc) and deallocation (free) as new nodes are added and old nodes are deleted.
when a node is deleted a function named delete is called.
I discovered that the program crashes sometimes when this delete-function is called and I KNOW that its something with the pointers in the method but I dont know WHERE in the code (row number) and WHY this happends.
I am used to high-level languages such as Java and I am used to encircle the problem by putting print-syntax at certain places in the method just to reveal WHERE it crashes.
I thought I could do the same with c and with pointer because to my knowledge I beleive the code is read from top to bottom that is 1, 2, 3, 4, and so on. (maybe interrupt handlers behave another way?)
So in this function named delete I have gone so far by putting this printf() at the very beginning of the delete-function - and all the same the program crashes.
So my Question - is it really possible that its some syntax in the delete-function (when I loop pointers for instance) that causes the crash WHEN not even the printf() is printing?
Am I wrong when I believe that the program is executed from to to bottom - that is 1, 2, 3 ....
You can se my printf-function in the very beginning of delete-function
And by the way - how could I solve this problem when I get this cryptic crash message from windows? See the bitmap!!
Greatful for answers!!!
int delete(int data) {
printf("IN THE BEGINNING OF DELETE!!!");
int result = 0;
if (queueref.last != NULL) {
node *curr_ptr;
node *prev_ptr;
node *temp_ptr;
if (queueref.first->data == data) {
temp_ptr = queueref.first;
queueref.first = queueref.first->next;
destroy_node(temp_ptr);
result = 1;
if (queueref.first == NULL) {
queueref.last = NULL;
puts("queue is now empty!!!");
}
} else {
prev_ptr = queueref.first;
curr_ptr = queueref.first->next;
printf("prev_ptr: %d\n", prev_ptr);
printf("curr_ptr: %d\n", curr_ptr);
while(curr_ptr != NULL) {
if (curr_ptr->data == data) {
result = 1;
if (curr_ptr->next != NULL) {
temp_ptr = curr_ptr;
destroy_node(temp_ptr);
prev_ptr->next = curr_ptr->next;
} else {
temp_ptr = curr_ptr;
queueref.last = prev_ptr;
prev_ptr->next = NULL;
destroy_node(temp_ptr);
}
}
curr_ptr = curr_ptr->next;
prev_ptr = prev_ptr->next;
}
}
}
return result;
}
Common mistake, here's the deal. This
printf("IN THE BEGINNING OF DELETE!!!");
needs to be
printf("IN THE BEGINNING OF DELETE!!!\n");
^^ note the newline
The reason is because stdio does not flush stdout until it sees a newline. If you add that newline, you should see the printf when the code enters the function. Without it, the program could crash, the stdout buffer would not have been flushed and would not see the printf.
Your code seems to have lots of implementation flaws. As a general advice I would recommend using some standard well-tested queue support library and static code analyzers (in this case you would even find dynamic analyzer valgrind very helpful, I guess).
For example, if implementation of destroy_node(ptr) is equivalent to free(ptr), then your code suffers from referencing destroyed data (or ,in other words, garbage) in this code snippet:
while(curr_ptr != NULL) {
if (curr_ptr->data == data) {
result = 1;
if (curr_ptr->next != NULL) {
temp_ptr = curr_ptr;
destroy_node(temp_ptr);
prev_ptr->next = curr_ptr->next; //<- curr_ptr is still in stack
//or register, but curr->next
//is garbage
// what if curr_ptr is first node? did you forget to update queueref.first?
} else {
temp_ptr = curr_ptr;
queueref.last = prev_ptr;
prev_ptr->next = NULL;
destroy_node(temp_ptr);
}
// if you you need to destroy only one node - you can leave the loop here with break;
}
curr_ptr = curr_ptr->next; /// assigning garbage again if node is found
prev_ptr = prev_ptr->next;
The reason why using destroyed data can work in * most * (if I can say that, basically this is unpredictable) cases is that the chances that this memory can be reused by other part of program for dynamically allocated data can vary on timings and code flow.
PS
Regarding cryptic messages in the Windows box - when program crashes OS basically generates crashdump and prints registers (and dumps some relevant memory parts). Registers and memory dumps can show the place of crash and immediate register/stack values but you have to now memory map and assembler output to understand it. Crashdump can be loaded to debugger (WinDbg) together with unstripped binary to check stactrace and values of local variables at the moment of crash. All these I described very very briefly, you could find tons of books / guides searching for "windows crash or crashdump analysis"

Pointer to Pointer

I am having a lot of trouble with this piece of code (I am not good at pointers :P). So here is the code.
printf("\n Enter the file name along with its extensions that you want to delete:-");
scanf("%s",fileName);
deletefile_1_arg=fileName;
printf("test\n");
result_5 = deletefile_1(&deletefile_1_arg, clnt);
if (result_5 == (int *) NULL) {
clnt_perror (clnt, "call failed");
}
else
{
printf("\n File is deleted sucessfully");
goto Menu2;
}
break;
Function that is getting called is as following.
int *
deletefile_1_svc(char **argp, struct svc_req *rqstp)
{
static int result;
printf("test2\n");
printf("%s",**argp);
if(remove(**argp));
{
printf("\nFile Has Been Deleted");
result=1;
}
return &result;
}
I am getting test2 on console but. It does not print value of argp / removes that perticular file. I am not sure what I am doing wrong. Please help me.
The argp is a pointer to a pointer char, and you are trying to use it as a pointer to char, try change your code to:
printf("%s", *argp);
You would also need to change your remove call to:
remove(*argp);
I always found drawing pictures helped understand pointers. Use boxes for memory addresses and a label for the box is the variable name. If the variable is a pointer, then the contents of the box is the address of another box (draw line to the other box).
You are using pointers when you don't need to. Your "deletefile1_svc" function doesn't manipulate the value of "argp" at all so it doesn't need a pointer-to-pointer. Plus your "result" doesn't need to be returned as a pointer since it is simply a numeric value. You also don't initialize result (it might be zero) or re-initialize it (it is static so it will remember the last value assigned to it).
int
deletefile_1_svc(const char *argp, struct svc_req *rqstp)
{
int result = 0; /* Initial value => failure */
if (remove (argp) == 0)
{
result = 1; /* 1 => success */
}
return result;
}
To call the function use:
result_5 = deletefile1_svc(filename, clnt);
if (result_5 == 0)
// Failed
else
// Success
That will make the code simpler and less prone to bugs.

Running out of memory.. How?

I'm attempting to write a solver for a particular puzzle. It tries to find a solution by trying every possible move one at a time until it finds a solution. The first version tried to solve it depth-first by continually trying moves until it failed, then backtracking, but this turned out to be too slow. I have rewritten it to be breadth-first using a queue structure, but I'm having problems with memory management.
Here are the relevant parts:
int main(int argc, char *argv[])
{
...
int solved = 0;
do {
solved = solver(queue);
} while (!solved && !pblListIsEmpty(queue));
...
}
int solver(PblList *queue) {
state_t *state = (state_t *) pblListPoll(queue);
if (is_solution(state->pucks)) {
print_solution(state);
return 1;
}
state_t *state_cp;
puck new_location;
for (int p = 0; p < puck_count; p++) {
for (dir i = NORTH; i <= WEST; i++) {
if (!rules(state->pucks, p, i)) continue;
new_location = in_dir(state->pucks, p, i);
if (new_location.x != -1) {
state_cp = (state_t *) malloc(sizeof(state_t));
state_cp->move.from = state->pucks[p];
state_cp->move.direction = i;
state_cp->prev = state;
state_cp->pucks = (puck *) malloc (puck_count * sizeof(puck));
memcpy(state_cp->pucks, state->pucks, puck_count * sizeof(puck)); /*CRASH*/
state_cp->pucks[p] = new_location;
pblListPush(queue, state_cp);
}
}
}
free(state->pucks);
return 0;
}
When I run it I get the error:
ice(90175) malloc: *** mmap(size=2097152) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Bus error
The error happens around iteration 93,000.
From what I can tell, the error message is from malloc failing, and the bus error is from the memcpy after it.
I have a hard time believing that I'm running out of memory, since each game state is only ~400 bytes. Yet that does seem to be what's happening, seeing as the activity monitor reports that it is using 3.99GB before it crashes. I'm using http://www.mission-base.com/peter/source/ for the queue structure (it's a linked list).
Clearly I'm doing something dumb. Any suggestions?
Check the result of malloc. If it's NULL, you might want to print out the length of that queue.
Also, the code snippet you posted didn't include any frees...
You need to free() the memory you've allocated manually after you're done with it; dynamic memory doesn't just "free itself"

Resources