allocating memory via malloc/calloc 
Author Message
 allocating memory via malloc/calloc

Thanks in advance,

I've written several functions which each has a single argument (character
strings) and returns the same (char string).  I need the function to return
a character string.  Each functions implementation dynamically allocates
memory to build a string for the work that the function does.

The problem?  Two lines prior to the function's return, I strcpy the
functions malloc'd character string (variable) to the global.  The line
prior to the functions return, I "free" the malloc'd (local) variable which
really upsets the compiler (Visual C++ 6.0).  One thing........"alloca"
worked great (but another compiler I have to port to doesn't support
"alloca", hence malloc or calloc.

Here's a synopsis of the problem:

#include<stdlib.h>
#include<stdio.h>
char * gvar;
char * start(char str[])
{
   char *lvar;
   if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
   {
      /* process */
      if ( strlen(gvar) < lvar)
      {
         if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL)
            strcpy(gvar, lvar);
      }
      free(lvar); /* ERROR */
   }
   return gvar;

Quote:
}

void main(void)
{
   if ( (gvar = (char *)malloc( 256) ) != NULL)
   {
      printf("%s\n", start("test"));  // would like function to return
character string as I next functions
   }

Quote:
}

As I said earlier, "alloca" worked fine (didn't have to "free" memory).
Any help would be greatly appreciated.


Wed, 09 Feb 2005 06:30:05 GMT  
 allocating memory via malloc/calloc

Quote:

> Thanks in advance,

> I've written several functions which each has a single argument (character
> strings) and returns the same (char string).  I need the function to
> return
> a character string.  Each functions implementation dynamically allocates
> memory to build a string for the work that the function does.

> The problem?  Two lines prior to the function's return, I strcpy the
> functions malloc'd character string (variable) to the global.  The line
> prior to the functions return, I "free" the malloc'd (local) variable
> which
> really upsets the compiler (visual c++ 6.0).  One thing........"alloca"
> worked great (but another compiler I have to port to doesn't support
> "alloca", hence malloc or calloc.

> Here's a synopsis of the problem:

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

#include <string.h>

Quote:
> char * gvar;
> char * start(char str[])
> {
>    char *lvar;
>    if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)

the cast of malloc is not necessairy and potentially dangerous.

Quote:
>    {
>       /* process */
>       if ( strlen(gvar) < lvar)

You compare the length of the string gvar points at to lvar ???

Quote:
>       {
>          if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL)

The first argument to realloc is a void * not a size_t. Read up on it in
your favourite C book or the FAQ of this newsgroup.

Quote:
>             strcpy(gvar, lvar);

lvar points to unitialised memory. This is not going to work

Quote:
>       }
>       free(lvar); /* ERROR */
>    }
>    return gvar;
> }
> void main(void)

int main(void)

Quote:
> {
>    if ( (gvar = (char *)malloc( 256) ) != NULL)
>    {
>       printf("%s\n", start("test"));  // would like function to return
> character string as I next functions
>    }
> }

> As I said earlier, "alloca" worked fine (didn't have to "free" memory).
> Any help would be greatly appreciated.

This code needs more work. What are you trying to do exactly?
Tobias

--
unix http://www.faqs.org/faqs/by-newsgroup/comp/comp.unix.programmer.html
clc http://www.eskimo.com/~scs/C-faq/top.html
fclc (french): http://www.isty-info.uvsq.fr/~rumeau/fclc/



Wed, 09 Feb 2005 04:19:35 GMT  
 allocating memory via malloc/calloc

Quote:

> Thanks in advance,

> I've written several functions which each has a single argument (character
> strings) and returns the same (char string).  I need the function to return
> a character string.  Each functions implementation dynamically allocates
> memory to build a string for the work that the function does.

> The problem?  Two lines prior to the function's return, I strcpy the
> functions malloc'd character string (variable) to the global.  The line
> prior to the functions return, I "free" the malloc'd (local) variable which
> really upsets the compiler (visual c++ 6.0).  One thing........"alloca"
> worked great (but another compiler I have to port to doesn't support
> "alloca", hence malloc or calloc.

You have a LOT more problems that that!

Quote:
> Here's a synopsis of the problem:

> #include<stdlib.h>
> #include<stdio.h>
> char * gvar;
> char * start(char str[])
> {
>    char *lvar;
>    if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
>    {
>       /* process */
>       if ( strlen(gvar) < lvar)

How is it you think you can compare a string length with a pointer to
char? What do you think it will tell you? What is it you really wanted
to do here? I can't figure it out.

Quote:
>       {
>          if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL)

You just took the string length of lvar, which doesn't at this time hold
anything. Very bad. You then passed that length as the first arg to
realloc(), which is looking for a pointer. What was it you were trying
to do here? Why isn't your compiler complaining like hell? The second
arg, which is supposed to be amount of memory you want, is sizeof
(char), which is always one. That will give you one byte only.

Also, you leaked whatever memory that gvar originally pointed to. If
your intent was to expand the buffer for gvar, then you needed to pass
it in as the first argument to realloc().

Quote:
>             strcpy(gvar, lvar);

You just copied the uninitialized contents of lvar to gvar. Kaboom.

Quote:
>       }
>       free(lvar); /* ERROR */

If the code you presented above is accurate, the heap is probably
trashed beyond help. That is normally what happens when free crashes.

Quote:
>    }
>    return gvar;

Why return a global variable? Why HAVE a global?

Quote:
> }
> void main(void)

main() must return an int.

Quote:
> {
>    if ( (gvar = (char *)malloc( 256) ) != NULL)
>    {
>       printf("%s\n", start("test"));  // would like function to return
> character string as I next functions
>    }
> }

You don't seem to understand the realloc() function at all. Please
review the documentation. On it.

Brian Rodenborn



Wed, 09 Feb 2005 04:51:08 GMT  
 allocating memory via malloc/calloc
Sorry.....

I keyed in the code from memory (not readily before me) and made a few
mistakes that you caught (see very bottom of email for full listing).

: >    if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
:
: the cast of malloc is not necessairy and potentially dangerous.
:

Saw this casting format in one of the C books I have....I'll remove it.

: >    {
: >       /* process */
: >       if ( strlen(gvar) < lvar)
:
: You compare the length of the string gvar points at to lvar ???
:

Typo......should have been
====> if (strlen(gvar) < strlen(lvar))

: >       {
: >          if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL)
:
: The first argument to realloc is a void * not a size_t. Read up on it in
: your favourite C book or the FAQ of this newsgroup.
:

Another typo (must have had calloc on the brain).  Should have been

=====> if ( (gvar = realloc( gvar, strlen(lvar) + 1 ) != NULL)

: >             strcpy(gvar, lvar);
:
: lvar points to unitialised memory. This is not going to work
:
: >       }
: >       free(lvar); /* ERROR */
: >    }
: >    return gvar;
: > }
: > void main(void)
:
: int main(void)
:
: > {
: >    if ( (gvar = (char *)malloc( 256) ) != NULL)
: >    {
: >       printf("%s\n", start("test"));  // would like function to return
: > character string as I next functions
: >    }
: > }
: >
: > As I said earlier, "alloca" worked fine (didn't have to "free" memory).
: > Any help would be greatly appreciated.
:

Here's the code minus typos (I hope) :-)

#include<stdlib.h>
#include<stdio.h>
char * gvar;
char * start(char str[])
{
   char *lvar;
   if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
   {
      /* process */
      if ( strlen(gvar) < strlen(lvar))
      {
         if ( (gvar = realloc( gvar, sizeof(char) ) != NULL)
            strcpy(gvar, lvar);
      }
      free(lvar); /* ERROR */
   }
   return gvar;

Quote:
}

void main(void)
{
   if ( (gvar = (char *)malloc( 256) ) != NULL)
   {
      printf("%s\n", start("test"));  // would like function to return
character string as I next functions
   }

Quote:
}

Thanks again...


Wed, 09 Feb 2005 08:19:33 GMT  
 allocating memory via malloc/calloc

Quote:

> Thanks in advance,

> I've written several functions which each has a single argument (character
> strings) and returns the same (char string).  I need the function to return
> a character string.  Each functions implementation dynamically allocates
> memory to build a string for the work that the function does.

> The problem?  Two lines prior to the function's return, I strcpy the
> functions malloc'd character string (variable) to the global.  The line
> prior to the functions return, I "free" the malloc'd (local) variable which
> really upsets the compiler (visual c++ 6.0).  One thing........"alloca"
> worked great (but another compiler I have to port to doesn't support
> "alloca", hence malloc or calloc.

> Here's a synopsis of the problem:

    You're going to receive quite a few comments about
things that have nothing to do with your actual problem,
but that's your own fault.  Why?  Because you didn't post
the actual code that's failing, but a "synopsis" that
won't even compile.

    I've read somewhere that in earlier times when Royalty
was considered sacrosanct and semi-divine, it would have
been an egregious breach of The Right Order Of Things for
a lowly commoner to lay hands on the Royal personage.  So
when a King fell ill, it was out of the question to allow a
doctor to examine the ailing monarch.  Instead, they'd use a
stand-in of lowlier lineage; this person would simulate the
King's illness to the best of his ability, and the doctor would
examine him instead.  Court protocol was thereby satisfied,
but I have a suspicion the diagnoses may have been suboptimal.

Quote:
> #include<stdlib.h>
> #include<stdio.h>
> char * gvar;
> char * start(char str[])
> {
>    char *lvar;
>    if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)

    The strlen() function hasn't been declared.  C90 compilers
may or may not complain about this (C99 compilers must do so),
but even if the compiler doesn't complain your program may
malfunction here.  The problem is that in the absence of a
declaration, the compiler will assume strlen() returns an
`int', but it actually returns a `size_t'.  Functions returning
`size_t' may use different conventions than those returning
`int', so the register (or whatever) where strlen() deposited
its `size_t' return value may not be the same place where the
caller retrieves the supposed `int' return value.

    The cure?  #include <string.h>.

Quote:
>    {
>       /* process */
>       if ( strlen(gvar) < lvar)

    This can't be right: you're comparing the integral value
returned by strlen() to the pointer variable `lvar'.  Integers
and pointers aren't comparable, and the compiler would have
given you a diagnostic here if you'd actually tried this code.

Quote:
>       {
>          if ( (gvar = realloc( strlen(lvar) + 1, sizeof(char) ) != NULL)

    This can't be right: the first argument to realloc() must
be a pointer, and you're passing an integral value.  Since the
#include <stdlib.h> line informed the compiler about realloc(),
the compiler would have issued a diagnostic -- again, if this
had been the actual code instead of a "synopsis."

Quote:
>             strcpy(gvar, lvar);

    `lvar' points to some allocated memory, but nothing has
actually been stored in that memory.  In particulary, there is
no guarantee the memory contains anything C would consider a
"string:" a sequence of characters (possibly empty) followed
by a byte with value zero.  Passing this uninitialized garbage
non-string as the second argument of strcpy() is a good way
to get demons to fly out of your nose.

Quote:
>       }
>       free(lvar); /* ERROR */

    I see no reason the compiler should complain about this (of
course, the compiler is always at liberty to complain about
whatever it feels like).  But, as we've already established,
this isn't the line the compiler complained about, because
this code never went through the compiler.

Quote:
>    }
>    return gvar;
> }
> void main(void)

    main() returns an int.  Period.

Quote:
> {
>    if ( (gvar = (char *)malloc( 256) ) != NULL)
>    {
>       printf("%s\n", start("test"));  // would like function to return
> character string as I next functions
>    }

    main() returns an int.  Period.

Quote:
> }

> As I said earlier, "alloca" worked fine (didn't have to "free" memory).
> Any help would be greatly appreciated.

    As I said earlier, you'll get more accurately-focused
help if you exhibit your actual problem instead of some
half-baked approximation.  "Synopsis" -- bah!

--



Wed, 09 Feb 2005 05:05:38 GMT  
 allocating memory via malloc/calloc

Quote:

> Sorry.....

> I keyed in the code from memory (not readily before me) and made a few
> mistakes that you caught (see very bottom of email for full listing).

Thanks for wasting everyone's time.

Quote:
> #include<stdlib.h>
> #include<stdio.h>
> char * gvar;
> char * start(char str[])
> {
>    char *lvar;
>    if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
>    {
>       /* process */
>       if ( strlen(gvar) < strlen(lvar))

What do you think the length of lvar will be, when you haven't set it to
anything? If you tell me it's another typo, I'm going to killfile your
sorry ass.

Quote:
>       {
>          if ( (gvar = realloc( gvar, sizeof(char) ) != NULL)
>             strcpy(gvar, lvar);

Here you copy the uninitialized buffer to gvar. That does, well who
knows what. See my note above.

Quote:
>       }
>       free(lvar); /* ERROR */

Again, crashes on free() usually means you donked up the heap doing
something bad with pointers or overrunning buffers.

I still think you should get rid of that global var. If you want to
expand the buffer, pass in the existing pointer and either return it's
value or the newly allocated expansion. Or pass in a char** and change
the pointer's value.

Brian Rodenborn



Wed, 09 Feb 2005 06:11:32 GMT  
 allocating memory via malloc/calloc


Wed, 18 Jun 1902 08:00:00 GMT  
 allocating memory via malloc/calloc
Everyone,

Thanks for the prior posts.......unfortunately I couldn't post the original
code due to constraints beyond my control and had to key in sample thru
memory of which I made typos for which I apologize.  Here's the code with
corrections:

#include<stdlib.h>
#include<stdio.h>
char * gvar;
char * start(char str[])
{
   char *lvar;
   if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)
   {
      /* process */
      if ( strlen(gvar) < strlen(lvar))
      {
         if ( (gvar = realloc( gvar, sizeof(char) ) != NULL)
            strcpy(gvar, lvar);
      }
      free(lvar); /* ERROR */
   }
   return gvar;

Quote:
}

void main(void)
{
   if ( (gvar = (char *)malloc( 256) ) != NULL)
   {
      printf("%s\n", start("test"));  // would like function to return
character string as I next functions
   }

Quote:
}

Now, I can eliminate declaration of gvar as global if the malloc' within
function implementation retains the memory (and data in its memory, the
heap). I declared the global variable initially because when I'd declare
within the function as an array of characters, then return that array
variable (last executable line within function), compiler error indicated it
was a local variable and removed from the stack.


Wed, 09 Feb 2005 09:41:35 GMT  
 allocating memory via malloc/calloc
On Fri, 23 Aug 2002 18:41:35 -0700, in comp.lang.c ,

Quote:

>#include<stdlib.h>
>#include<stdio.h>
>char * gvar;

don't use global variables unless you have to. I see from the below
that you're trying not to though !

Quote:
>char * start(char str[])
>{
>   char *lvar;
>   if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)

The cast is unnecessary and potentially dangerous in C. See many many
other posts in this group.

Quote:
>   {
>      /* process */
>      if ( strlen(gvar) < strlen(lvar))

At this point, gvar contains random garbage, since you never copied
any data into it. Performing strlen on it is lethally dangerous.

Quote:
>      {
>         if ( (gvar = realloc( gvar, sizeof(char) ) != NULL)

NEVER use realloc like this. If the realloc fails, you just leaked
memory. To use it safely, you must use a temporary intermediate
variable as several other posters have stated I believe.

Also, you just realloced the memory down to one byte. Is that what you
intended? I suspect not.

Quote:
>            strcpy(gvar, lvar);

This just trashed your stack because gvar points to memory one byte
long, and you copied 5 bytes into it.

Quote:
>      }
>      free(lvar); /* ERROR */

yes, this is likely. you tried to use strlen on garbage, then tried to
copy 5 bytes into a space made for one. So you've corrupted your
computer memory.

Quote:
>   }
>   return gvar;

don't return global variables, its pointless.

Quote:
>}
>void main(void)

as you've been told, C requires main to return an int.

Quote:
>{
>   if ( (gvar = (char *)malloc( 256) ) != NULL)

don't cast malloc. Also, this does not initialise the contents of
gvar, so it contains garbage. You can't use strlen on a pointer to
garbage.

Quote:
>   {
>      printf("%s\n", start("test"));  // would like function to return
>character string as I next functions
>   }
>}

>Now, I can eliminate declaration of gvar as global if the malloc' within
>function implementation retains the memory (and data in its memory, the
>heap).

memory malloc'ed is retained until _you_ free it.

Quote:
> I declared the global variable initially because when I'd declare
>within the function as an array of characters, then return that array
>variable (last executable line within function), compiler error indicated it
>was a local variable and removed from the stack.

either your implementation is broken, or you returned something
peculiar. You should be returning the local variable, not its address.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>



Wed, 09 Feb 2005 08:22:17 GMT  
 allocating memory via malloc/calloc

Quote:

> Everyone,

> Thanks for the prior posts.......unfortunately I couldn't post the original
> code due to constraints beyond my control and had to key in sample thru
> memory of which I made typos for which I apologize.  Here's the code with
> corrections:

> #include<stdlib.h>
> #include<stdio.h>
> char * gvar;
> char * start(char str[])
> {
>    char *lvar;
>    if ( (lvar = (char *)malloc( strlen(str) * 2 + 1) ) != NULL)

The malloc cast is unnecessary, and you'd be better off without it.

Quote:
>    {
>       /* process */
>       if ( strlen(gvar) < strlen(lvar))

gvar points at 256 bytes of memory of an indeterminate nature. Thus, the
call to strlen here invokes undefined behaviour.

Quote:
>       {
>          if ( (gvar = realloc( gvar, sizeof(char) ) != NULL)

You should use a temporary pointer to catch the value of realloc, in
case it fails. Note that sizeof(char) is 1, so what you just did was
throw away 255 of your 256 bytes of memory.

Quote:
>             strcpy(gvar, lvar);

lvar doesn't have any determinate contents, so you have undefined
behaviour again.

Quote:
>       }
>       free(lvar); /* ERROR */
>    }
>    return gvar;
> }
> void main(void)

int main(void)

Quote:
> {
>    if ( (gvar = (char *)malloc( 256) ) != NULL)

Remove the cast.

Quote:
>    {
>       printf("%s\n", start("test"));  // would like function to return
> character string as I next functions
>    }
> }

> Now, I can eliminate declaration of gvar as global if the malloc' within
> function implementation retains the memory (and data in its memory, the
> heap).

So long as you have a pointer to it, you have access to your malloc'd
memory. If your pointer goes out of scope, you can't get its value back.

Quote:
> I declared the global variable initially because when I'd declare
> within the function as an array of characters, then return that array
> variable (last executable line within function), compiler error indicated it
> was a local variable and removed from the stack.

It was correct to indicate that problem.

The following program does what I *think* you intend:

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

char *start(const char *str, char *p, size_t psize)
{
  char *newp = p;
  size_t len = strlen(str);
  if(len >= psize)
  {
    newp = realloc(p, len + 1);
  }

  if(newp != NULL)
  {
    strcpy(newp, str);
  }
  else
  {
    newp = p;
  }

  return newp;

Quote:
}

int main(void)
{
  char *p = malloc(256);

  if(p != NULL)
  {
    p = start("test", p, 256);
    printf("%s\n", p);
    free(p);
  }

  return 0;

Quote:
}

--

"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton


Wed, 09 Feb 2005 08:39:58 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. freeing the memory allocated by calloc

2. doubt - freeing the memory allocated by calloc

3. getting the size of allocated memory via Marshal.SizeOf

4. newbie malloc problem: free memory allocated to structures

5. Where does malloc allocate memory?

6. Determining amount of memory allocated by malloc()

7. Allocating memory to a multidimensional array using malloc ??

8. calloc() - Allocating pointers in structures?

9. How to use calloc to allocate >64K in Visual C++

10. Override malloc,calloc,realloc and free?

11. Problems changing from Malloc to Calloc

12. calloc VS malloc ??

 

 
Powered by phpBB® Forum Software