Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Avoid using malloc?

Reply
Thread Tools

Avoid using malloc?

 
 
Keith Thompson
Guest
Posts: n/a
 
      03-02-2006
Johs32 <(E-Mail Removed)> writes:
> Richard Heathfield wrote:
>
>> Johs32 said:
>>
>>> #include<stdio.h>
>>> #include<stdlib.h>
>>>
>>> void print_me(char * string)
>>> {
>>> printf("%s\n",string);
>>> }
>>>
>>>
>>> int main()
>>> {
>>> char *string = "bopla";

>>
>> This pointer points to a string literal, which has static storage duration
>> and therefore exists for the duration of the program. Nothing wrong with
>> this code (although I'd make it const char * if you're pointing at a
>> string literal).

>
> Ok but what is *string was a pointer to a struct or something that is not a
> "literal", can I still omit malloc?


It depends on how you allocate it and what you do with it. We
couldn't answer your original question without seeing code; we can't
answer this one without seeing code either.

If you declare a local variable (i.e., declare it inside a function
without using the "static" keyword), that variable ceases to exist
when you leave the function. If you create a pointer to a local
variable, returning that pointer to a caller invokes undefined
behavior -- but you can safely pass the pointer to another function,
since the variable continues to exist until the outer function
terminates.

Returning the *value* of a local variable is ok.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
 
 
 
Pedro Graca
Guest
Posts: n/a
 
      03-02-2006
Johs32 wrote:
> ups forgot the code:
>
>
> #include<stdio.h>
> #include<stdlib.h>
>
> void print_me(char * string)
> {
>
>
> printf("%s\n",string);
> }
>
>
> int main()
> {
> char *string = "bopla";
> print_me(string);
> return 0;
> }


And now you forgot the question.

Please provide context, even when following-up to your own posts.
Also read the link in my signature.

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
 
Reply With Quote
 
 
 
 
Micah Cowan
Guest
Posts: n/a
 
      03-02-2006
Johs32 <(E-Mail Removed)> writes:

> Richard Heathfield wrote:
>
> > Johs32 said:
> >
> >> #include<stdio.h>
> >> #include<stdlib.h>
> >>
> >> void print_me(char * string)
> >> {
> >> printf("%s\n",string);
> >> }
> >>
> >>
> >> int main()
> >> {
> >> char *string = "bopla";

> >
> > This pointer points to a string literal, which has static storage duration
> > and therefore exists for the duration of the program. Nothing wrong with
> > this code (although I'd make it const char * if you're pointing at a
> > string literal).
> >

>
> Ok but what is *string was a pointer to a struct or something that is not a
> "literal", can I still omit malloc?


Well, given the order of calling that you had, it still would've been
fine, even if it had been an object of automatic storage duration:

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

void print_me(const char *string)
/* ^^^^^ I consider this a bit better. */
{
printf("%s\n", string);
/* The above could more easily be: puts(string); */
}

int main(void)
/* ^^^^ this is very much worth spelling out: not the same as (). */

char string[] = "bopla";
print_me(string);
return EXIT_SUCCESS;
}
--------------------------------------------------

This works, because the automatically-allocated object exist until
main() exits.

However, if you had reversed the calling:

----------------- BAD CODE !! --------------------
#include <stdio.h>
#include <stdlib.h>

char *get_string(void)
{
char string[] = "message";
return string; /* string[] disappears after this ! */
}

int main(void)
{
puts(get_string());
return EXIT_SUCCESS;
}
----------------- BAD CODE !! --------------------

This causes problems, for the reason explained in the comment.
You could fix it by declaring string[] as:

static char string[] = "message";

which would give it a static storage duration (same lifetime as a
literal).

Or--especially if you don't know how big it will need to be, or if
you need a separate copy of the string for each caller (perhaps you
intend for it to be modified)--you'll need to malloc() it. Always make
sure you free() it again later, so the system can reclaim the lost
memory.

HTH,
Micah
 
Reply With Quote
 
Jordan Abel
Guest
Posts: n/a
 
      03-02-2006
On 2006-03-02, Johs32 <(E-Mail Removed)> wrote:
> Richard Heathfield wrote:
>
>> Johs32 said:
>>
>>> #include<stdio.h>
>>> #include<stdlib.h>
>>>
>>> void print_me(char * string)
>>> {
>>> printf("%s\n",string);
>>> }
>>>
>>>
>>> int main()
>>> {
>>> char *string = "bopla";

>>
>> This pointer points to a string literal, which has static storage duration
>> and therefore exists for the duration of the program. Nothing wrong with
>> this code (although I'd make it const char * if you're pointing at a
>> string literal).
>>

>
>
> Ok but what is *string was a pointer to a struct or something that is not a
> "literal", can I still omit malloc?


passing it down without using malloc is fine - the problem comes when
you're _returning_ something.
 
Reply With Quote
 
gooch
Guest
Posts: n/a
 
      03-03-2006

Michael Mair wrote:
> Johs32 schrieb:
> Please provide compiling code, ideally stripped down to the
> situation you are referring to -- otherwise there is always
> the danger of misunderstandings.
>
> Example 1: The following is legal:
>
> void foo (long *bar);
> void baz (void);
>
> int main (void)
> {
> baz();
> return 0;
> }
>
> void baz (void)
> {
> long qux = 17;
> long *quux = &qux;
> foo(quux);
> }
>
> void foo (long *bar)
> {
> *bar /= 2;
> }
>


This seems fine although useless

> Example 2: The following is not legal:
>
> long *foo (void);
> void baz (void);
>
> int main (void)
> {
> baz();
> return 0;
> }
>
> void baz (void)
> {
> long *quux = foo();


doesn't foo have an argument?

> *quux -= 2;
> }
>
> void foo (long *bar)
> {
> long bar = 42;
> long *qux = &bar;
> return qux;


This is a void function with a return value, why?
> }
>
> I did not test either example.
> Even if you are in the situation of example 2, it is
> perfectly possible that it works


I could be wrong but I don't think number 2 will even compile.

> Example 3: malloc()-Version of Example 2; legal
>
> #include <stdlib.h>
>
> long *foo (void);
> void baz (void);
>
> int main (void)
> {
> baz();
> return 0;
> }
>
> void baz (void)
> {
> long *quux = foo();


again there is an argument to foo.

> if (quux != NULL) {

you will never get here.
> *quux -= 2;
> }

what are you freeing here as you bnever allocated anything
> free(quux);
> }
>
> void foo (long *bar)
> {
> long *qux = malloc(sizeof *qux);
> if (qux != NULL) {
> *qux = 42;
> }
> return qux;


You are agin returning a value from a void function
> }


Again I could be wrong but I don't think this will compile. Am I
missing something here.

 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      03-03-2006
gooch schrieb:
> Michael Mair wrote:
>
>>Johs32 schrieb:
>>Please provide compiling code, ideally stripped down to the
>>situation you are referring to -- otherwise there is always
>>the danger of misunderstandings.
>>
>>Example 1: The following is legal:
>>
>>void foo (long *bar);
>>void baz (void);
>>
>>int main (void)
>>{
>> baz();
>> return 0;
>>}
>>
>>void baz (void)
>>{
>> long qux = 17;
>> long *quux = &qux;
>> foo(quux);
>>}
>>
>>void foo (long *bar)
>>{
>> *bar /= 2;
>>}

>
> This seems fine although useless


Yes. All the examples are fine and useless. I wanted
to describe the possible situations.

>>Example 2: The following is not legal:
>>
>>long *foo (void);
>>void baz (void);
>>
>>int main (void)
>>{
>> baz();
>> return 0;
>>}
>>
>>void baz (void)
>>{
>> long *quux = foo();

>
>
> doesn't foo have an argument?


According to the prototype, it does not.
I just forgot to change the prototype for the function
definition accordingly -- as I said, untested.
>
>
>> *quux -= 2;
>>}
>>
>>void foo (long *bar)

long *foo (void)

>>{
>> long bar = 42;
>> long *qux = &bar;
>> return qux;

>
>
> This is a void function with a return value, why?


See above.
>
>>}
>>
>>I did not test either example.
>>Even if you are in the situation of example 2, it is
>>perfectly possible that it works

>
>
> I could be wrong but I don't think number 2 will even compile.
>
>
>>Example 3: malloc()-Version of Example 2; legal
>>
>>#include <stdlib.h>
>>
>>long *foo (void);
>>void baz (void);
>>
>>int main (void)
>>{
>> baz();
>> return 0;
>>}
>>
>>void baz (void)
>>{
>> long *quux = foo();

>
>
> again there is an argument to foo.
>
>
>> if (quux != NULL) {

>
> you will never get here.
>
>> *quux -= 2;
>> }

>
> what are you freeing here as you bnever allocated anything
>
>> free(quux);
>>}
>>
>>void foo (long *bar)

long *foo (void)
>>{
>> long *qux = malloc(sizeof *qux);
>> if (qux != NULL) {
>> *qux = 42;
>> }
>> return qux;

>
>
> You are agin returning a value from a void function
>
>>}

>
> Again I could be wrong but I don't think this will compile. Am I
> missing something here.


Same applies here.
Thanks for asking for a correction


Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
Ron Lima
Guest
Posts: n/a
 
      03-03-2006
> Ok but what is *string was a pointer to a struct or something that is not a
> "literal", can I still omit malloc?


If you make it point to some place in memory, yes. For instance:

#include <stdio.h>

struct test {
int a;
char b[40];
};
int main (void) {
struct test s = {10, "Hello there"};
struct test *p = &s;

printf ("%d %s\n", p->a, p->b);
return 0;
}

In this case, p points to the storage provided by s. Usually you
allocate memory when you don't know how much information you will have
to deal in memory and this fact makes it impossible to pre-allocate
storage for it. For instance, imagine that you need to read an entire
file to memory in order to do some processing on it. Since the file can
have an arbitrary lenght, you just can't pre-allocate memory and,
therefore, you will need to allocate memory for your buffer before
reading the entire file.

 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      03-12-2006
On Thu, 02 Mar 2006 21:30:34 +0100, Johs32 <(E-Mail Removed)> wrote:

>Richard Heathfield wrote:
>
>> Johs32 said:
>>
>>> #include<stdio.h>
>>> #include<stdlib.h>
>>>
>>> void print_me(char * string)
>>> {
>>> printf("%s\n",string);
>>> }
>>>
>>>
>>> int main()
>>> {
>>> char *string = "bopla";

>>
>> This pointer points to a string literal, which has static storage duration
>> and therefore exists for the duration of the program. Nothing wrong with
>> this code (although I'd make it const char * if you're pointing at a
>> string literal).
>>

>
>
>Ok but what is *string was a pointer to a struct or something that is not a
>"literal", can I still omit malloc?


When your function receives a pointer from a calling routine, you do
not necessarily need to call malloc.

If the calling routine tries to pass you an uninitialized
pointer, that routine invokes undefined behavior and anything can
happen before, during, or after your function executes.

Now that you know the pointer has been initialized to some
value, it may be appropriate to check if that value is NULL. You do
this if your function would normally try to dereference the pointer
since dereferencing a NULL pointer would invoke undefined behavior.

If you want to change the value of the pointer (the address it points
to), you could call malloc. You could also assign it the address of
an object of the correct type that happens to be in scope to your
function. Whether you do this or not depends on the nature of your
function. Since C passes arguments to functions by value, any change
you make to the pointer's value is local to your function unless you
somehow "export" the new value to the calling routine, as with a
return statement.

In my experience, most functions that receive pointers as arguments do
not call malloc but use the value of the pointer as passed by the
calling routine. I think you should go back and reread the text that
raised your initial question. All automatic variables local to your
function, including parameters, disappear when your function returns.
However, this has no affect on the variables in the calling routine
that may have been used as arguments.


Remove del for email
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Using enums to avoid using switch/if aks_java Java 30 03-25-2010 11:48 AM
Avoid having a SQL express for web parts and avoid personalization Roger23 ASP .Net 2 10-12-2006 10:54 PM
using TagPrefix to avoid having @ Register directives on pages using custom controls Shan McArthur ASP .Net Building Controls 2 06-30-2005 02:37 PM
Using Command object to avoid dynamic sql Bob Barrows [MVP] ASP .Net 1 04-05-2005 12:57 PM
Avoid wasting time or how to avoid initialization Alexander Malkis C++ 8 04-13-2004 11:23 PM



Advertisments