Thread: dynamic buffers

  1. #1
    Registered User
    Join Date
    Aug 2005
    Posts
    9

    dynamic buffers

    Code:
    char *str_cat(char *s1, const char *s2)
    {
        if ((s1 = (char *)realloc(s1, strlen(s1) + strlen(s2) + 1)) == NULL) {
            perror("mem.c: str_cat(): realloc()");
            return NULL;
        }
    
        strcat(s1, s2);
    
        return s1;
    }
    could someone please enlighten me as to why realloc() keeps crashing my program? the function definitely works, but it seems to only work for a randomly small number of times before it craps out. i've read the man page probably 20 times, as well as googling for help, but i can't seem to see any reason for this behavior. thanks in advance!

    p.s. 's1' has been allocated (or reallocated) before every call.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You're probably munging up your pointers elsewhere. You're probably either giving realloc a bad pointer, some place you shouldn't be pointing, or it's not crashing in the realloc call at all, but some place else. If it is crashing there, it's you not keeping track of your pointers correctly, and giving it bad stuff to play with.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,663
    > if ((s1 = (char *)realloc(s1, strlen(s1) + strlen(s2) + 1)) == NULL)
    1. Don't cast malloc functions in C (read the FAQ)
    2. Assign the result of malloc to a temporary variable first. If realloc returns NULL, then the memory which s1 points to is still VALID. Except now you have a memory leak because you just trashed s1.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    I read the link.

    This was something I didn't know before. But I'm wondering, what is the purpose of the n in:
    Code:
    p = malloc ( n * sizeof *p );
    Pentium 4 - 2.0GHz, 512MB RAM
    NVIDIA GeForce4 MX 440
    WinXP
    Visual Studio .Net 2003
    DX9 October 2004 Update (R.I.P. VC++ 6.0 Compatability)

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,663
    n is how many you want
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Aug 2005
    Posts
    9
    first of all, thanks to both of you for attempting to help me.

    to quzah: i've debugged the program and it is definitely crashing in the call to realloc. the pointer is also valid (i made sure to test this before i posed the problem) and is pointing exactly where i want it to point. this is why i'm having such a hard time figuring it out.

    Code:
    (gdb) up
    #7  0x0804cc6e in str_cat (s1=0x973f0e8 "        ", s2=0x804e14b "\033[1m") at mem.c:85
    85          if ((s1 = (char *)realloc(s1, strlen(s1) + strlen(s2) + 1)) == NULL) {
    and to salem: thanks for the tips, but unfortunately i don't think either will help solve the current problem. i appreciate your help though!

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    If realloc is crashing your program, it's not realloc's fault. You're passing it pointers you shouldn't. What do you mean by "valid"? Not null?
    Code:
    char *p, *t;
    
    p = malloc( 2 );
    strcpy( p, "a" );
    while( strlen( p ) < 1000 )
    {
        t = realloc( p, strlen( p ) + 2 );
        if( t )
        {
            strcat( t, "a" );
            p = t;
            printf("p is \'%s\'\n", p );
        }
        else
            break;
    }
    free( p );
    Does this crash?


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User
    Join Date
    Aug 2005
    Posts
    9
    yes that works just fine.

    i don't understand how it could be what i'm passing to it? as you can see from the gdb output, both pointers passed to the function are valid, non-NULL pointers and there is readable/usable data at each memory location. if it helps at all, the strings that these 2 pointers are pointing to have each been run through this same function multiple times successfully before it crashes.

  9. #9
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Simply being non-NULL doesn't mean it's valid. Are you incrementing these ponters some place perhaps? Is one a string literal? It could be numerous things. Try posting some more code rather than just that piece.


    Quzah.
    Hope is the first step on the road to disappointment.

  10. #10
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    n is how many you want
    Whoa whoa...
    Code:
    double *p;
    
    p = malloc ( n * sizeof *p );
    That's out of the FAQ post...

    So you're saying that you could use p to technically store more than one double?
    Would accessing be anything close to (this is off the top of my head):
    Code:
    double *p;
    
    p = malloc (2 * sizeof *p );
    
    *p = 20;
    
    *(p + sizeof(double)) = 30;
    Well that doesn't seem right at all. I'm not exactly sure how memory addresses are assigned for consecutive variables like that there...if you get what I mean...

    Anyways, does does the n pretty much just refer to character arrays? Or would there also be an implementation for ints, floats, etc.?
    Pentium 4 - 2.0GHz, 512MB RAM
    NVIDIA GeForce4 MX 440
    WinXP
    Visual Studio .Net 2003
    DX9 October 2004 Update (R.I.P. VC++ 6.0 Compatability)

  11. #11
    Registered User
    Join Date
    Aug 2005
    Posts
    9
    quzah: i wasn't referring to the fact that it was non-NULL being the reason it was valid, i was referring to the fact that the gdb output...

    Code:
    #7  0x0804cc6e in str_cat (s1=0x973f0e8 "        ", s2=0x804e14b "\033[1m") at mem.c:85
    ...shows that the pointers 's1' and 's2' are valid pointers due to the fact that the data being pointed to by them is readable/printable (displayed in quotes).

    there is really no other code relevant to the problem, you can see the function itself and what was passed to it. personally i can see no reason why the function would not have worked given the pointers/data it had to work with.
    Last edited by derrickn; 08-04-2005 at 04:47 PM.

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by derrickn
    there is really no other code relevant to the problem, you can see the function itself and what was passed to it. personally i can see no reason why the function would not have worked given the pointers/data it had to work with.
    Why is it no one here ever believes me? Of course there's relevant code. You want to know why? Because this works just fine:
    Code:
    char *str_cat(char *s1, const char *s2)
    {
        if ((s1 = (char *)realloc(s1, strlen(s1) + strlen(s2) + 1)) == NULL) {
            perror("mem.c: str_cat(): realloc()");
            return NULL;
        }
    
        strcat(s1, s2);
    
        return s1;
    }
    
    int main( void )
    {
        char *p, *t;
    
        p = malloc( 2 );
        str_cat( p, "a" );
        while( strlen( p ) < 1000 )
        {
            t = str_cat( p, "a" );
            if( t )
                p = t;
        }
    
        puts( p );
        free( p );
    
        return 0;
    }
    But rather than believe me, and post your whole broken example, you'd rather believe a standard library function (realloc) is broken, and that it couldn't possibly be anything you're doing.


    Quzah.
    Hope is the first step on the road to disappointment.

  13. #13
    Registered User
    Join Date
    Aug 2005
    Posts
    9
    ok, obviously i don't believe that there is a bug in realloc(), and i never said i did - that would be just plain stupid.

    the reason there is no other relevant code is because code outside this function does not affect the function's actions. only the data/values passed to it and the code within the function itself affect its actions. and since i've given you both of these, it's fair to say i've given you all relevant code.

    the only thing i can think of right now that may be causing the problem is if when i realloc(), the newly requested chunk oversteps some boundary. is this possible?

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by derrickn
    the reason there is no other relevant code is because code outside this function does not affect the function's actions. only the data/values passed to it and the code within the function itself affect its actions. and since i've given you both of these, it's fair to say i've given you all relevant code.
    That would be nice, if it were true. Your mishandling of pointers can cause all kinds of fun. Which, as I stated initially, is likely what you've done.
    Quote Originally Posted by derrickn
    the only thing i can think of right now that may be causing the problem is if when i realloc(), the newly requested chunk oversteps some boundary. is this possible?
    Well then that would definately be a problem with realloc then, wouldn't it? Since we're both in agreement now that it isn't realloc that's the problem, that leaves you.

    If you don't feel like posting your code, that's fine. Maybe some one else with a crystal ball will tell you where you've gone wrong. I'm done trying to get you to help yourself fix your problem. Ciao.


    Quzah.
    Hope is the first step on the road to disappointment.

  15. #15
    Registered User
    Join Date
    Aug 2005
    Posts
    9
    well, here are the pieces used. if you can find anything in the additional code thats relevant to solving my problem, then i apologize.

    Code:
    // -------------------------- mem.c ---------------------------
    
    char *str_cat(char *s1, const char *s2)
    {
        char    *tmp;
    
        if ((tmp = realloc(s1, strlen(s1) + strlen(s2) + 1)) == NULL) {
            perror("mem.c: str_cat(): realloc()");
            return NULL;
        }
    
        strcat(tmp, s2);
        s1 = tmp;
    
        return s1;
    }
    
    char *str_new(const char *s)
    {
        char    *new;
    
        if ((new = malloc(strlen(s) + 1)) == NULL) {
            perror("mem.c: str_new(): malloc()");
            return NULL;
        }
    
        strcpy(new, s);
    
        return new;
    }
    
    // ------------------------ comm.c -------------------------
    
        char    *out;
    
        out = str_new("");
    
    // ---- loop through another string here, char by char, and
    // check for |R and other codes ----
    
                    case 'R':   if (out) { str_cat(out, FRED);      } else { out = str_new(FRED);       }   break;
    there you have it... i only included case R because its the first and only case that applies to the string being processed.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  2. dynamic array/vector help
    By Cpro in forum C++ Programming
    Replies: 8
    Last Post: 04-05-2008, 03:30 PM
  3. Identify dynamic IP address of network device
    By BobS0327 in forum Tech Board
    Replies: 2
    Last Post: 02-21-2006, 01:49 PM
  4. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM
  5. Dynamic memory confusion
    By ripper079 in forum C++ Programming
    Replies: 5
    Last Post: 11-04-2002, 06:15 PM