Re: passing pointers [C]
From: Barry Schwarz (schwarzb_at_deloz.net)
Date: 07/09/04
- Next message: Peter: "Re: Default constructors, passing argument"
- Previous message: Bert: "Re: Dynamically allocating memory for handles"
- In reply to: Stephen Ramsay: "passing pointers [C]"
- Next in thread: Stephen Ramsay: "Re: passing pointers [C]"
- Reply: Stephen Ramsay: "Re: passing pointers [C]"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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>>
- Next message: Peter: "Re: Default constructors, passing argument"
- Previous message: Bert: "Re: Dynamically allocating memory for handles"
- In reply to: Stephen Ramsay: "passing pointers [C]"
- Next in thread: Stephen Ramsay: "Re: passing pointers [C]"
- Reply: Stephen Ramsay: "Re: passing pointers [C]"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|