Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Trying to figure out how to dynamically re-allocate strings while concatenating (http://www.velocityreviews.com/forums/t949073-trying-to-figure-out-how-to-dynamically-re-allocate-strings-while-concatenating.html)

Shriramana Sharma 08-04-2012 02:12 PM

Trying to figure out how to dynamically re-allocate strings while concatenating
 
Hello. I am not a professional programmer and only program now and then. So please forgive me if my question sounds silly or naive.

I am trying to find out how to dynamically lengthen a string while concatenating in C, as it is easily possible to do so in C++ or Python (two other languages I have used).

I patched up the following code:

Code:

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

void strappend ( char * a, char * b )
{
a = ( char * ) realloc ( a, strlen ( a ) + strlen ( b ) ) ;
strcat ( a, b ) ;
}

void main ( void )
{
char * name = "my name is" ;
strappend ( name, " this or " ) ;
strappend ( name, "that." ) ;
printf ( "%s\n", name ) ;
}

But it aborts with an error saying: "./strappend: realloc(): invalid pointer: 0x000000000040073c ***". No matter how many times I execute it that hex number remains the same.

Can anyone kindly point me to what I am doing wrong with realloc? I have never really used malloc/realloc stuff so I am probably botching things up somewhere but I'm not sure where.

Thanks!

Xavier Roche 08-04-2012 02:17 PM

Re: Trying to figure out how to dynamically re-allocate strings whileconcatenating
 
Le 04/08/2012 16:12, Shriramana Sharma a écrit :
> a = ( char * ) realloc ( a, strlen ( a ) + strlen ( b ) ) ;

.....................................^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^

+1 for the ending \0



Xavier Roche 08-04-2012 02:22 PM

Re: Trying to figure out how to dynamically re-allocate strings whileconcatenating
 
Le 04/08/2012 16:12, Shriramana Sharma a écrit :
> char * name = "my name is" ;


Oh, and you can't do that, too.

char * name = strdup("my name is");

Otherwise the string will be a constant, not a valid malloc() pointer.

(building with -Werror=write-strings might be a good idea)



Shriramana Sharma 08-04-2012 02:25 PM

Re: Trying to figure out how to dynamically re-allocate strings while concatenating
 
Hey very nice thank you very much for that guidance! :-) It's now working.

Heinrich Wolf 08-04-2012 02:29 PM

Re: Trying to figure out how to dynamically re-allocate strings while concatenating
 

"Shriramana Sharma" <jamadagni@gmail.com> schrieb im Newsbeitrag
news:eb47af15-f8ff-4737-983d-3f54307c1081@googlegroups.com...
> Hello. I am not a professional programmer and only program now and then.
> So please forgive me if my question sounds silly or naive.
>
> I am trying to find out how to dynamically lengthen a string while
> concatenating in C, as it is easily possible to do so in C++ or Python
> (two other languages I have used).
>
> I patched up the following code:
>
>
Code:

> # include <stdio.h>
> # include <stdlib.h>
> # include <string.h>
>
> void strappend ( char * a, char * b )
> {
> a = ( char * ) realloc ( a, strlen ( a ) + strlen ( b ) ) ;
> strcat ( a, b ) ;
> }

Code:


You are changing a in this function, but a is restored on leaving it. So you
need to declare
void strappend ( char ** a, char * b )

strlen ( a ) + strlen ( b )
is not enough! You need to add 1 char for the terminating 0.

> void main ( void )
> {
> char * name = "my name is" ;
> strappend ( name, " this or " ) ;
> strappend ( name, "that." ) ;
> printf ( "%s\n", name ) ;
> }
>



You are reallocating memory in strappend, but not freeing it. This short
program is ok. The reallocated "name" is still in reach and automatically
freed on exiting your program. But be careful in a more complex program!

I doubt that realloc is allowed on the initial value of "name", since it was
not malloc'ed. In fact it is a pointer aiming at constant memory segment.
Maybe
char * name = strdup("my name is");
works better.

> But it aborts with an error saying: "./strappend: realloc(): invalid
> pointer: 0x000000000040073c ***". No matter how many times I execute it
> that hex number remains the same.
>
> Can anyone kindly point me to what I am doing wrong with realloc? I have
> never really used malloc/realloc stuff so I am probably botching things up
> somewhere but I'm not sure where.
>
> Thanks!



Eric Sosman 08-04-2012 02:52 PM

Re: Trying to figure out how to dynamically re-allocate strings whileconcatenating
 
On 8/4/2012 10:12 AM, Shriramana Sharma wrote:
> Hello. I am not a professional programmer and only program now and then. So please forgive me if my question sounds silly or naive.
>
> I am trying to find out how to dynamically lengthen a string while concatenating in C, as it is easily possible to do so in C++ or Python (two other languages I have used).
>
> I patched up the following code:
>
>
Code:

> # include <stdio.h>
> # include <stdlib.h>
> # include <string.h>
>
> void strappend ( char * a, char * b )

Code:


Aside: `strappend' is a reserved name (anything starting with
`str...' is reserved), and it's conceivable you could get into trouble.
Change the name.

> {
>        a = ( char * ) realloc ( a, strlen ( a ) + strlen ( b ) ) ;


The end of a string is marked by a '\0' character, which is *not*
included in the string's length.  The string "Hello" has length five,
but requires six bytes: 'H', 'e', 'l', 'l', 'o', '\0'.  You are
allocating one byte less than you actually need.


>        strcat ( a, b ) ;


Functions that acquire resources can fail.  When realloc() cannot
find enough memory to satisfy your request, it returns NULL -- and if
you blindly use that NULL as the first argument to strcat(), you'll
be in Deep Trouble.  Get in the habit of always checking the returned
value before using it -- and this goes for any function that acquires
a resource, whether you're requesting memory or trying to open a file
or anything: If the function can fail, you should check for failure.

But even if realloc() and strcat() work fine, now what?  You began
with a pointer `a', which is a local variable inside strappend().  You
use realloc() to change that local variable; it changes.  But how will
your caller learn of the change?  Answer: It won't.  What happens in
strappend() stays in strappend().  The call to strappend() provided an
initial value for `a', but that's all: There is no "reverse path" from
`a' back to the expression that provided the value.  You will have to
get the value back to the caller by some other route, perhaps by
returning it as the value of the strappend() function (there are other
ways, but this seems simplest).

> }
>
> void main ( void )


Aside: `int main(void)'.

> {
>        char * name = "my name is" ;
>        strappend ( name, " this or " ) ;


No, no, no!  You can only RE-allocate memory that was dynamically
allocated to begin with, that is, memory that you earlier obtained
from realloc() or malloc() or calloc().  The variable `name' points
to memory that is statically allocated, not dynamic: If you attempt to
realloc() that non-dynamic memory, you get "undefined behavior."  (It
is likely that the specific message you're seeing is due to exactly
this problem.)

>        strappend ( name, "that." ) ;
>        printf ( "%s\n", name ) ;


As mentioned earlier, `name' has not been affected by what went
on inside strappend().

> }
>


>
> But it aborts with an error saying: "./strappend: realloc(): invalid pointer: 0x000000000040073c ***". No matter how many times I execute it that hex number remains the same.
>
> Can anyone kindly point me to what I am doing wrong with realloc? I have never really used malloc/realloc stuff so I am probably botching things up somewhere but I'm not sure where.


The comp.lang.c Frequently Asked Questions (FAQ) page at
<http://www.c-faq.com/> would make good reading. Section 4 is
all about pointers -- in fact, Question 4.8 specifically addresses
one of the problems in your code.

The C programming languages has many strengths, but hand-holding
is not among them. You need to be something of a shade-tree mechanic
or tinkerer (or even gearhead) to use C well. If you're an occasional
programmer and not much interested in fiddly low-level details, you
may be happier with a higher-level, more coddling language. I think
Mark Twain wrote that one lifetime is not long enough to master
German; something similar could be said of C.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Ben Bacarisse 08-04-2012 03:04 PM

Re: Trying to figure out how to dynamically re-allocate strings while concatenating
 
Shriramana Sharma <jamadagni@gmail.com> writes:

> Hey very nice thank you very much for that guidance! :-) It's now
> working.


Take care. Many C programs appear to work, right up to the point where
they don't! I hope you have taken all the advice, not just the advice
in the message to which you replied.

Speaking of which, strdup is not a standard C function, so you should
check that it will available everywhere your program might run (or at
least everywhere your program might be compiled and linked).

--
Ben.

Stefan Ram 08-04-2012 03:28 PM

Re: Trying to figure out how to dynamically re-allocate strings while concatenating
 
Shriramana Sharma <jamadagni@gmail.com> writes:
>Can anyone kindly point me to what I am doing wrong with realloc?


The result of an attempt should always be checked according
to me. The »free« below is not really required for this
small program, but would be helpful in many cases, where the
code is repeatedly executed in a program.

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

char * strapp( char * * const a, char const * const b )
{ *a = realloc( *a, 1 + strlen( *a )+ strlen( b ));
if( *a )strcat( *a, b );
return *a; }

int main( void )
{ char const * const name_ = "my name is";
char * name = malloc( strlen( name_ )+ 1 );
if( name )
{ strcpy( name, name_ );
if( strapp( &name, " this or " ))
if( strapp( &name, "that." ))
printf( "%s\n", name );
free( name ); }}


Eric Sosman 08-04-2012 05:56 PM

Re: Trying to figure out how to dynamically re-allocate strings whileconcatenating
 
On 8/4/2012 12:27 PM, pete wrote:
>[...]
> I see from your call to the free function,
> that you intend to free the allocated memory within main.
>
> If either call to strapp returns a null pointer,
> then your call to free, will free a null pointer instead.


... which is harmless, defined as a no-op.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Eric Sosman 08-04-2012 06:00 PM

Re: Trying to figure out how to dynamically re-allocate strings whileconcatenating
 
On 8/4/2012 12:42 PM, pete wrote:
>[...]
> One thing that nobody else has mentioned,
> is that it is good programming practice
> to assign the return value of realloc
> to a temporary pointer first,
> and only to assign that value to your working pointer
> if the temporay pointer has been tested
> and found to be not a null pointer.
>
> Otherwise you lose
> the value of the pointer to the allocated memory,
> which can cause a memory leak.


Note that his realloc() call and value assignment were
inside a function that received the pointer value as an
argument. That is, the caller still owns (or can compute)
a pointer to the allocated memory.

Still, (1) the O.P.'s code was pretty badly messed up
already and we're all in the business of imagining different
possible corrections to it, and (2) your advice to assign
the value of realloc(p,...) to something other than p is
usually excellent.

--
Eric Sosman
esosman@ieee-dot-org.invalid


All times are GMT. The time now is 08:06 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.