Re: passing pointers [C]

From: Barry Schwarz (schwarzb_at_deloz.net)
Date: 07/09/04


Date: 8 Jul 2004 23:32:00 GMT

On Thu, 08 Jul 2004 20:17:30 GMT, Stephen Ramsay <sramsay@uga.edu>
wrote:

>I've got a problem that probably stems from some fundamental
>misunderstandings on my part.
>
>My app has to concatenate strings to build up a bunch of SQL queries
>(some elements of which aren't known until runtime. Now, I realize that
>I could malloc some space, concatenate the first two, malloc some more,
>concatenate again, but this seems less than elegant. So, I thought I
>would create a separate cat_string function that would take in the
>strings, do that malloc, and return a new string.
>
>The problem with this implementation, is that while it works (compiles
>and produces the expected behaviour), it's leaking memory all over the
>place -- I assume because it's really creating new copies and failing to
>de-allocate the old ones.

Since you only call realloc, there is no way for old allocations not
to be released. Your problem stems from the fact that you are using
it incorrectly and invoking undefined behavior.

>
>Be that as it may, it seems to me that the most efficient way to do this
>would be to keep passing in the current string (the one that is being
>gradually built up) and realloc-ing it's memory block. When all the
>concatenations are completed, it could then just free that one block.
>
>In my limited understanding of C, I start to think, "Hmm. Something to
>do with passing addresses, um, help . . ."
>
>So, here's some (toy) code. It's really a mess -- seg faults every time
>-- and it's really just the latest iteration of "well, let's try this."
>It should, though, give you an idea of what I'm trying to do. If anyone
>can give me a hint, I'd really appreciate it.
>
>#include <stdio.h>
>#include <string.h>
>#include <stdlib.h>
>
>static void cat_string(char **left, char *right);

Part of you confusion would probably disappear if you let the function
return the address of the newly reallocated memory instead of trying
to be fancy with the double pointer.

>
>int main(void)
>{
> char *target = "";

You may want to change this to
     char *target = NULL;

>
> char *string1 = "Welcome ";
> char *string2 = "to ";
> char *string3 = "C ";
> char *string4 = "Programming ";
> char *string5 = "for ";
> char *string6 = "the confused.";
>
> cat_string(&target, string1);

The way things are coded now, the first argument is the address of a
pointer and the value assigned to that pointer is not the address of
an area previously allocated by malloc/calloc/realloc.

> cat_string(&target, string2);
> cat_string(&target, string3);
> cat_string(&target, string4);
> cat_string(&target, string5);
> cat_string(&target, string6);
>
> printf("%s\n", target);
>
> free(target);
>
> return 0;
>
>}
>
>static void cat_string(char **left, char *right)
>{
>
> realloc(*left, (strlen(*left) + strlen(right) + 1)
> * sizeof(char *));

Surely you mean sizeof(char), not char*.

Regardless, this invokes undefined behavior the first time it is
called. The first argument to realloc must be either NULL or the
address that was previously allocated by one of the three allocation
routines.

> strcat(*left, right);

This is wrong regardless. realloc does not change the argument it was
passed. It returns the value so you can assign it to a variable. The
value in *left can very possibly be the address of memory you no
longer own.

You probably want to change these two statements to something like

     temp = realloc(*left, ....);
     if (temp == NULL)
          {/*error logic*/}
     else {
          *left = temp;
          strcat(...);
          }

You also need to think about how you want the calling function to know
that cat_string failed.

>
>}
>
>Thanks,
>
>Steve

<<Remove the del for email>>



Relevant Pages

  • Re: was: Current Uses for Fortran ??
    ... > Strange because no other programming languages do it. ... > numbers and strings. ... I don't like + for concatenate since I believe that concatenate ... no deficiencies and the other way is to make it so complicated ...
    (comp.lang.fortran)
  • passing pointers [C]
    ... My app has to concatenate strings to build up a bunch of SQL queries ... I could malloc some space, concatenate the first two, malloc some more, ... gradually built up) and realloc-ing it's memory block. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: Best practices for efficient FP string building in CL?
    ... CONCATENATE fast: ... (defun smarter-concatenate-strings (strings) ... (defun not-so-clever-concatenate (strings) ...
    (comp.lang.lisp)
  • Re: Console.WriteLine(s) Is Missing Line Terminator?
    ... If I don't know if those are strings or numerics, ... It's the ease with which it encourages lazy programming that puts me off ... Matius is arguing strongly that '+' should not be used to concatenate ... reasons", to me it's like saying "Say Hasta La Vista to ...
    (microsoft.public.dotnet.general)
  • Re: Building HTML - String vs Array
    ... Concatenate Strings: ... Build Using Arrays: ... Use either arrays or string concatenation, whichever suits. ...
    (comp.lang.javascript)