Boston Linux & Unix (BLU) Home | Calendar | Mail Lists | List Archives | Desktop SIG | Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings
Linux Cafe | Meeting Notes | Blog | Linux Links | Bling | About BLU

BLU Discuss list archive


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Segmentation fault



On Mon, 7 Feb 2000, Jerry Feldman wrote:

> This could be a malloc quirk. I don;t know what algorithms are used by
> malloc in glibc. Some mallocs try to give you exactly what you ask
> for, but malloc is also required to give you a pointer which is always
> on a "natual", boundary. There should be nothing special about 12.  
> You call rest_of_string(temp, i), in a for loop where i varies from 0
> to (len - 1). In the final case:

Here is the malloc and `for' loop:

    /* store the string without the current char in temp */    
    temp = (char *)malloc( len * sizeof(char) + 1 );
    done_so_far = (char *)malloc( strlen( done ) + 2);
   
    for ( i = 0; i < len; i++ ) {
      strcpy( done_so_far, done );
      strcpy( temp, string );
      temp = rest_of_string( temp, i );
      charcurrent[0] = string[i];
      strcat( done_so_far, charcurrent );
      permutation( temp, done_so_far );
    }


The first malloc now correctly allocates the full size of the string, as
you can see.  Note that this fixes the problem.

Here again is the rest_of_string() function:

    char *
    rest_of_string( char *string, int usedchar )
    {
  
      string[usedchar] = '\0';
      strcat( string, (string + usedchar + 1) );
      return string;
  
    }

Let's use the test case of "abc" as the example.  The code is indented,
and my comments and variable display are not.

string = "abc\0"
len = 3
size of temp = 4 ( len + 1 )
elements of temp are 0-3, { 'a','b','c','\0' }

Since temp is allocated to hold 4 chars, I will show its value enumerating
all 4 of the characters, even when there are multiple sequential nulls.

case: i = len - 1 = 2

so we'll make the call to rest_of_sting( string = "abc\0", usedchar = 2 )

	string[usedchar] = '\0'

string now = "ab\0\0"
string[usedchar + 1] = '\0' 

	strcat( string, (string + usedchar + 1) );

stores the concatenation of string = "ab\0" and (string + usedchar + 1) =
(string + 2 + 1) = (string + 3) = the string starting at string[3] = "\0"

or 

	strcat ( "ab", "\0" );

which puts "ab\0" [ size = 3, len = 2 ] in string, which is exactly what
is needed. Works like a charm.

string now = "ab\0\0"

No array overrun.

Convinced?  If not, I'll send you the full source code (it's very small),
and you can run it through the debugger. The key was simply to make sure
temp is allocated large enough to hold the original string, including its
terminating null. Evidently I was smashing a malloc pointer. I still find
it strange that it worked when the argument was < 12 chars, but it's
probably just a coincidence based on the implementation of malloc.

Thanks again for your help.  I seem to have a habit of being bitten by
counting errors... I must really watch out for that.  I have to admit I
haven't ever coded this particular type of counting error, and was quite
baffled by the call to free() causing a segfault. Now I know what to look
for if it happens again! :)

-- 
"Quis custodiet ipsos custodes?"    "Who watches the watchmen?" 
-Juvenal, Satires, VI, 347 

Derek D. Martin      |  Senior UNIX Systems/Network Administrator
Arris Interactive    |  A Nortel Company
derekm at mediaone.net  |  dmartin at ne.arris-i.com
-------------------------------------------------

-
Subcription/unsubscription/info requests: send e-mail with
"subscribe", "unsubscribe", or "info" on the first line of the
message body to discuss-request at blu.org (Subject line is ignored).




BLU is a member of BostonUserGroups
BLU is a member of BostonUserGroups
We also thank MIT for the use of their facilities.

Valid HTML 4.01! Valid CSS!



Boston Linux & Unix / webmaster@blu.org