On Friday, August 23, 2013 1:15:42 PM UTC-4, Sharwan Joram wrote:
> Hi,
>
> I have a strange problem here in my code. I'am getting memory corruption while trying to free the first element of list. Code snippet and GDB debugging trace below :
>
>
>
> ---------------------------------- code
>
> char **parameters;
>
> int idx;
>
> int parametercount;
>
> char *saved_token, token;
>
>
>
> parameters = (char **)malloc(parametercount * sizeof(char *)); // Don't use *parameters it breaks.
>
> for( parametercount = 0 , token = strtok(saved_token, " "); token && *token ; ++parametercount , token = strtok(NULL, " ")){
>
> parameters[parametercount] = (char *)malloc(30 * sizeof (char *));
>
> memset(parameters[parametercount], '\0', 30);
>
> memcpy(parameters[parametercount], token, strlen(token));
>
> parameters[parametercount] = token;
>
> }
>
>
>
> /* idx contains the number of tokens */
>
> if (parameters != NULL){
>
> for (parametercount = idx; parametercount >= 0; ++parametercount)
>
> free(parameters[parametercount]);
>
> free(parameters);
>
> }
>
>
>
> ---------- Debugging session trace ----
>
>
>
> 160 memcpy(temp_token, saved_token, strlen(saved_token));
>
> (gdb)
>
> 161 idx = parametercount = detect_delim_count(temp_token, delimiters);
>
> (gdb)
>
> 162 if (temp_token)
>
> (gdb)
>
> 163 free(temp_token);
>
> (gdb) n
>
> 171 parameters = (char **)malloc(parametercount * sizeof(char *)); // Don't use *parameters it breaks.
>
> (gdb)
>
> 172 for( parametercount = 0 , token = strtok(saved_token, " "); token && *token ; ++parametercount , token = strtok(NULL, " ")){
>
> (gdb)
>
> 173 parameters[parametercount] = (char *)malloc(30 * sizeof (char *));
>
> (gdb) p parameters
>
> $1 = (char **) 0xb6e0f828
>
> (gdb) n
>
> 174 memset(parameters[parametercount], '\0', 30);
>
> (gdb)
>
> 175 memcpy(parameters[parametercount], token, strlen(token));
>
> (gdb)
>
> 172 for( parametercount = 0 , token = strtok(saved_token, " "); token && *token ; ++parametercount , token = strtok(NULL, " ")){
>
> (gdb)
>
> 173 parameters[parametercount] = (char *)malloc(30 * sizeof (char *));
>
> (gdb) p parameters
>
> $2 = (char **) 0xb6e0f828
>
> (gdb) n
>
> 174 memset(parameters[parametercount], '\0', 30);
>
> (gdb) p parameters[parametercount]
>
> $3 = 0xb6e0f8b8 ""
>
> (gdb) n
>
> 175 memcpy(parameters[parametercount], token, strlen(token));
>
> (gdb)
>
> 172 for( parametercount = 0 , token = strtok(saved_token, " "); token && *token ; ++parametercount , token = strtok(NULL, " ")){
>
> (gdb) p parameters[parametercount]
>
> $4 = 0xb6e0f8b8 "param2"
>
> (gdb) n
>
> 173 parameters[parametercount] = (char *)malloc(30 * sizeof (char *));
>
> (gdb)
>
> 174 memset(parameters[parametercount], '\0', 30);
>
> (gdb) p parameters[parametercount]
>
> $5 = 0xb6e0f938 ""
>
> (gdb)
>
> $6 = 0xb6e0f938 ""
>
> (gdb) n
>
> 175 memcpy(parameters[parametercount], token, strlen(token));
>
> (gdb) p parameters[parametercount]
>
> $7 = 0xb6e0f938 ""
>
> (gdb) n
>
> 172 for( parametercount = 0 , token = strtok(saved_token, " "); token && *token ; ++parametercount , token = strtok(NULL, " ")){
>
> (gdb) p parameters[parametercount]
>
> $8 = 0xb6e0f938 "param3"
>
> (gdb) n
>
> 173 parameters[parametercount] = (char *)malloc(30 * sizeof (char *));
>
> (gdb)
>
> 174 memset(parameters[parametercount], '\0', 30);
>
> (gdb)
>
> 175 memcpy(parameters[parametercount], token, strlen(token));
>
> (gdb)
>
> 172 for( parametercount = 0 , token = strtok(saved_token, " "); token && *token ; ++parametercount , token = strtok(NULL, " ")){
>
> (gdb) p parameters[parametercount]
>
> $9 = 0xb6e0f9b8 "param4"
>
> (gdb) n
>
> 201 shutdown = (currentcommand->command_handler)(client_fd, parameters, parametercount);
>
> (gdb)
>
> 211 executedcommand = currentcommand;
>
> (gdb)
>
> 216 currentcommand = currentcommand->next;
>
> (gdb)
>
> 127 while((executedcommand == NULL) && (currentcommand != NULL)){
>
> (gdb)
>
> 221 if (parameters != NULL){
>
> (gdb)
>
> 222 for (parametercount = idx; parametercount >= 0; ++parametercount)
>
> (gdb) p parameters
>
> $10 = (char **) 0xb6e0f828
>
> (gdb) p parameters[parametercount]
>
> $11 = 0x61726170 <Address 0x61726170 out of bounds>
>
> (gdb) n
>
> 223 free(parameters[parametercount]);
>
> (gdb) p parameters[parametercount]
>
> $12 = 0xb6e0f9b8 "param4"
>
> (gdb) n
>
> *** glibc detected *** /home/sources/opennop-daemon/opennopd/opennopd: corrupted double-linked list: 0xb6e0f820 ***
>
> ======= Backtrace: =========
>
> /lib/libc.so.6[0x4441a1d1]
>
> /lib/libc.so.6[0x4441a7bd]
>
> /home/sources/opennop-daemon/opennopd/opennopd[0x805294c]
>
> /home/sources/opennop-daemon/opennopd/opennopd[0x80520c5]
>
> /lib/libpthread.so.0[0x4455fadf]
>
> /lib/libc.so.6(clone+0x5e)[0x4449944e]
>
> ======= Memory map: ========
>
> 08048000-08056000 r-xp 00000000 fd:01 397476 /home/sources/opennop-daemon/opennopd/opennopd
>
> 08056000-08057000 rw-p 0000d000 fd:01 397476 /home/sources/opennop-daemon/opennopd/opennopd
> b21ff000-b2200000 ---p 00000000 00:00 0
>
> b2200000-b2a00000 rw-p 00000000 00:00 0 [stack:846]
>
> b2a00000-b2b00000 rw-p 00000000 00:00 0
>
> b2bf9000-b2bfa000 ---p 00000000 00:00 0
>
> b2bfa000-b33fa000 rw-p 00000000 00:00 0 [stack:844]
>
> b33fa000-b33fb000 ---p 00000000 00:00 0
>
> b33fb000-b3bfb000 rw-p 00000000 00:00 0 [stack:843]
>
> b3bfb000-b3bfc000 ---p 00000000 00:00 0
>
> b3bfc000-b43fc000 rw-p 00000000 00:00 0 [stack:842]
>
> b43fc000-b43fd000 ---p 00000000 00:00 0
>
> b43fd000-b4bfd000 rw-p 00000000 00:00 0 [stack:840]
>
> b4bfd000-b4bfe000 ---p 00000000 00:00 0
>
> b4bfe000-b53fe000 rw-p 00000000 00:00 0 [stack:836]
>
> b53fe000-b53ff000 ---p 00000000 00:00 0
>
> b53ff000-b5bff000 rw-p 00000000 00:00 0 [stack:835]
>
> b5bff000-b5c00000 ---p 00000000 00:00 0
>
> b5c00000-b6400000 rw-p 00000000 00:00 0 [stack:834]
>
> b6400000-b6500000 rw-p 00000000 00:00 0
>
> b65ff000-b6600000 ---p 00000000 00:00 0
>
> b6600000-b6e00000 rw-p 00000000 00:00 0 [stack:833]
>
> b6e00000-b6e2a000 rw-p 00000000 00:00 0
>
> b6e2a000-b6f00000 ---p 00000000 00:00 0
>
> b6fd2000-b6fd3000 ---p 00000000 00:00 0
>
> b6fd3000-b77d3000 rw-p 00000000 00:00 0 [stack:832]
>
> b77d3000-b77d4000 ---p 00000000 00:00 0
>
> b77d4000-b7fd6000 rw-p 00000000 00:00 0 [stack:831]
>
> b7fd6000-b7fda000 r-xp 00000000 fd:01 165010 /usr/lib/libmnl.so.0.1.0
>
> b7fda000-b7fdb000 r--p 00003000 fd:01 165010 /usr/lib/libmnl.so.0.1.0
>
> b7fdb000-b7fdc000 rw-p 00004000 fd:01 165010 /usr/lib/libmnl.so.0.1.0
>
> b7fdc000-b7fe2000 r-xp 00000000 fd:01 165001 /usr/lib/libnfnetlink.so.0.2.0
>
> b7fe2000-b7fe3000 r--p 00005000 fd:01 165001 /usr/lib/libnfnetlink.so.0.2.0
>
> b7fe3000-b7fe4000 rw-p 00006000 fd:01 165001 /usr/lib/libnfnetlink.so.0.2.0
>
> b7fe4000-b7fe5000 rw-p 00000000 00:00 0
>
> b7fe5000-b7feb000 r-xp 00000000 fd:01 148876 /usr/lib/libnetfilter_queue.so.1.3.0
>
> b7feb000-b7fec000 r--p 00005000 fd:01 148876 /usr/lib/libnetfilter_queue.so.1.3.0
>
> b7fec000-b7fed000 rw-p 00006000 fd:01 148876 /usr/lib/libnetfilter_queue.so.1.3.0
>
> b7ffc000-b7fff000 rw-p 00000000 00:00 0
>
> b7fff000-b8000000 r-xp 00000000 00:00 0 [vdso]
>
> bffdf000-c0000000 rw-p 00000000 00:00 0 [stack]
>
>
>
> I am unable to understand the reason of this behaviour.
>
>
>
> --Regards,
>
> Sharwan Joram
/* small steps may help */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXNUMBER 5
int main( void )
{
char **a; /* a pointer to a pointer of type char */
int numberOfPointers = 5;
/* a points to an allocated block of memory which are pointers */
/* in this case 5 such pointer. */
a = (char **) malloc ( numberOfPointers * ( sizeof(char * ) ) );
/* check to see if space was allocated */
/* and print a message if it was */
if ( a!= NULL )
printf( "the array, a, points to declare space\n\n" );
/* declare and iniitialized an array of pointers to characters */
char *b[] = { "one", "two", "three", "four", "five" };
/* pointer assignment */
a = b;
/*
using the pointer to pointer of type char, a, print
the strings of character array b.
*/
for ( int index = 0; index < 5; index++ )
{
printf( "%s\n\n", *(a+index) );
}
/*
find the size of a sting of characters
*/
char *string = "word" ;
size_t n = strlen( string );
printf("\n %zd \n\n", n); /* %zd because n is of type size_t */
/*
declare an array of characters, sentence[]
declare a token, which is a pointer to a string constant, " ".
declare a pointer to a character.
*/
char sentence[] = "this is a sentence with words";
char *token = " ";
char *g;
/*
grab the first word of the character array sentence.
char *strtok( char *s1, const char *s2 );
strtok needs an array of character passed as char *s1 on my machine. when a pointer to a string constant is use
a memory problem occurs.
get the length of the first word, after a call to strtok().
size_t strlen( const char *s );
print the length of that string, the first word in the arrary of characters, with a message.
*/
g = strtok(sentence, token);
size_t y = strlen(g);
printf("the length of the first word in the sentence is %d\n\n", (int) y );
/*
using the length of the string, of the first word, from the char sentence array,
char sentence[], allocate some space that will hold characters plus one more. assign a pointer,
c_space, char *c_space, to point to that created space.
print a message if space was allocated.
*/
char *c_space = (char *) malloc( y * sizeof(char) + 1 );
if (c_space)
{
printf("got space for word\n\n");
}
/* create and array using the length of the first word plus one copy */
int indexnewstring = (int) y + 1; /* (int) strlen( g ) + 1 */
char newstring[indexnewstring];
/* copy the first word into newstring and print string */
char *v = strcpy( newstring, g);
printf(" %s\n", v );
/*
create a second sentence array, char sentence2[], and through the sentence using a token to
separate each word.
*/
char sentence2[] = "this is a sentence with words";
g = strtok( sentence2, token );
while ( g != NULL )
{
printf("\n %s", g );
g = strtok( NULL, token );
}
printf("\n");
char sentence3[] = "C programming is fun execpt for pointers, actually it's the most fun";
for( g = strtok(sentence3, token ); g != NULL; g = strtok( NULL, token ) )
printf (" %s\n", g );
return 0;
}