Avoid using malloc?

J

Johs32

When I make a pointer I have read that if I would like to use it in another
function, I need to malloc it first else it will disapear after the
function returns. In this code I do not use malloc, but it still works and
the function print_me() prints the correct text.

Why does it work eventhough I do not use malloc?

johs
 
R

Richard Heathfield

Johs32 said:
When I make a pointer I have read that if I would like to use it in
another function, I need to malloc it first else it will disapear after
the function returns. In this code

In which code?
 
M

Michael Mair

Johs32 said:
When I make a pointer I have read that if I would like to use it in another
function, I need to malloc it first else it will disapear after the
function returns. In this code I do not use malloc, but it still works and
the function print_me() prints the correct text.

Why does it work eventhough I do not use malloc?

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;
}

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();
*quux -= 2;
}

void foo (long *bar)
{
long bar = 42;
long *qux = &bar;
return qux;
}

I did not test either example.
Even if you are in the situation of example 2, it is
perfectly possible that it works -- now. This can
change when compiling it on another operating system,
platform or with another compiler or even when just
adding another function to your code.

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();
if (quux != NULL) {
*quux -= 2;
}
free(quux);
}

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


Cheers
Michael
 
K

Kevin Handy

Johs32 said:
When I make a pointer I have read that if I would like to use it in another
function, I need to malloc it first else it will disapear after the
function returns. In this code I do not use malloc, but it still works and
the function print_me() prints the correct text.

Why does it work eventhough I do not use malloc?

Blind stupid luck is the most likely answer.

If that is the level of reliability you are looking
for in your programs, then go ahead and use it.

btw: What code?
 
K

Keith Thompson

Johs32 said:
When I make a pointer I have read that if I would like to use it in another
function, I need to malloc it first else it will disapear after the
function returns. In this code I do not use malloc, but it still works and
the function print_me() prints the correct text.

Why does it work eventhough I do not use malloc?

Why does *what* work? How do you "make" the pointer?

Show us some code, preferably a complete program.

But first, take a look at questions 7.5a and 7.5b in the comp.lang.c
FAQ, <http://www.c-faq.com/>.
 
J

Johs32

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;
}
 
R

Richard Heathfield

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).
 
J

Johs32

Richard said:
Johs32 said:


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?
 
R

Richard Heathfield

Johs32 said:
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 need to store data, you need somewhere to store it.

String literals are sorted out for you. If you wish to capture and store a
string at runtime, you will need to allocate storage for it. The malloc
function offers one way to do this.
 
K

Keith Thompson

Johs32 said:
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.
 
P

Pedro Graca

Johs32 said:
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.
 
M

Micah Cowan

Johs32 said:
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
 
J

Jordan Abel

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.
 
G

gooch

Michael said:
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.
 
M

Michael Mair

gooch said:
This seems fine although useless

Yes. All the examples are fine and useless. I wanted
to describe the possible situations.
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.long *foo (void)
This is a void function with a return value, why?

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




again there is an argument to foo.



you will never get here.


what are you freeing here as you bnever allocated anything



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
 
R

Ron Lima

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.
 
B

Barry Schwarz

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

malloc 40
MALLOC problem 25
Copy string from 2D array to a 1D array in C 1
Correct use of malloc 9
Malloc question 9
array-size/malloc limit and strlen() failure 26
gcc knows about malloc() 68
malloc and maximum size 56

Members online

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top