[Sussex] More C programming help

Mike Diack mike_diack at hotmail.com
Fri May 13 07:24:28 UTC 2005


Simple to explain...

- Your malloc is allocating space for 100 bytes (it's argument is always in
bytes). You are then treating this (via the cast) as a pointer to a set of
pointers ("an array").
- The for loop is trying to initialise an array of 100 char * pointers, each
member of the array to NULL. _BUT_ a pointer variable takes more memory than
1 byte. (Check the value
of:  sizeof (char *)  if you don't believe me). In fact typically on a 32
bit machine, each pointer is going to take 4 bytes, and thus the 100 bytes
you've allocated can only
accomodate 25 of the blighters! (Biggles speak!)

Mike

 

-----Original Message-----
From: sussex-bounces at mailman.lug.org.uk
[mailto:sussex-bounces at mailman.lug.org.uk] On Behalf Of Captain Redbeard
Sent: 12 May 2005 23:22
To: sussex at mailman.lug.org.uk
Subject: [Sussex] More C programming help

Alright guys, explain this one!

Here's the original program:

#include <stdio.h>
#include <stdlib.h>

int main()
{
   int i = 0;
   int ArraySize = 100;
   char **CharArray;

   CharArray = (char **) malloc (ArraySize);

   int X = 100;

   for (i=0; i<X; i++)
   {
     CharArray[i] = NULL;
   }

   printf ("free()ing CharArray.\n");
   free (CharArray);
   return 0;
}


This simply creates an array of strings, allocates memory to
  the array, NULLs every element of the array and then frees the memory.
However when I run this I get the following:

free()ing CharArray.
*** glibc detected *** double free or corruption (out): \ 0x08049710 ***
Aborted

i.e. it got as far as the free() command and then crashed. 
Exploring this a bit I discovered that if I put the value of X at 25, that
is NULL just the first 25 elements, the program compiles and runs fine and
Valgrind is also happy with it but if I put X=26 then it crashes again.
Further exploration revealed that whatever value I put ArraySize at the
program will ALWAYS crash if X is more than ArraySize/4 but if X is only
ArraySize/4 or less then no crash and no errors reported by Valgrind.  This
was the case even when I put ArraySize = 100,000,000.  If X was 25,000,000
then all is OK but if X = 25,000,001 then it crashes.  Looking into this
further I re-wrote the program as follows:

#include <stdio.h>
#include <stdlib.h>

int main()
{
   int ArraySize = 100;
   char **CharArray;

   CharArray = (char **) malloc (ArraySize);

   int X = 50;

   CharArray[X] = NULL;

   printf ("free()ing CharArray.\n");
   free (CharArray);
   return 0;
}

Now the program runs fine and doesn't crash but Valgrind reports a "Invalid
write of size 4" in line 13 (CharArray[X] = NULL;).  It will do this for ANY
value of X that is greater then ArraySize/4.  From this it seems that the
command "(char **) malloc (ArraySize)" only allocates
ArraySize/4 elements so that if I want to have ArraySize elements I should
make the line "(char **) malloc (ArraySize*4)" which **seems** to work fine
but why the hell would I need to do that?  What the hell am I missing?



--
Captain Redbeard



======================================================
Insomnia - it's not a condition, it's a mentality.
Registered Linux user: 388693.
Registered Linux machines: 289172, 289173.
v2sw5+8C+JGhw5ln4/5pr6/7Ock1ma6/8l6+8Sw3+2e4t2b9Hen4+6
g5+3RHaIr9 Hackerkey.com
======================================================

_______________________________________________
Sussex mailing list
Sussex at mailman.lug.org.uk
Sussex LUG Website: http://www.sussex.lug.org.uk/
http://mailman.lug.org.uk/mailman/listinfo/sussex




More information about the Sussex mailing list