malloc experiments

  • Thread starter Steve Zimmerman
  • Start date
S

Steve Zimmerman

Esteemed contributors to clc:

Thank you for all the responses.

Experiments 2 and 3 below are identical, except that
experiment 2 does not call free(), while experiment 3 does.

With such a trivial program, is it safe not to call free()?

Are there dangers in experiment 2 that experiment 3 avoids?

In what contexts does freeing memory become crucial?

In what contexts does freeing memory not matter?

This is not homework; I have read section 7 of the FAQ.

--Steve

####################### Experiment 2 (malloc) #################


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

int main()
{
char *h = malloc(30);
if (h == NULL)
fprintf(stderr, "No memory allocation\n");

printf("Successful memory allocation\n");

/* no call to free */

return 0;
}

Output: Successful memory allocation


####################### Experiment 3 (malloc) #################

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

int main()
{
char *h = malloc(30);
if (h == NULL)
fprintf(stderr, "No memory allocation\n");

printf("Successful memory allocation\n");

free(h); /* call to free */

return 0;
}

Output: Successful memory allocation


################################################################
 
D

Dave Vandervies

Esteemed contributors to clc:

Thank you for all the responses.

Experiments 2 and 3 below are identical, except that
experiment 2 does not call free(), while experiment 3 does.

With such a trivial program, is it safe not to call free()?

Safe, yes. (But wise, no. See below.) All the memory you malloc()d,
whether or not you free()d it, will (well, will if you have a hosted
implementation whose implementors attempted to provide a nonnegative
quality of implementation) be released when the program finishes.

Are there dangers in experiment 2 that experiment 3 avoids?

Forming bad habits.
(While probably not the kind of answer you were looking for, this is
probably the most important one.)

Unless you have a very good reason not to, you should avoid relying on
the implementation to clean up for you.

In what contexts does freeing memory become crucial?

Long-running programs, or components of programs that get called a large
number of times.
That second one is important even if you're writing a trivial program that
(at the moment) does its work and exits immediately. By not freeing the
memory you allocate, you're gratuitiously making it harder to embed your
program into another program that could usefully use its functionality,
since the memory that fgets released when the program exits will get
leaked when it finishes and returns to the larger program.

In what contexts does freeing memory not matter?

When know that you have more virtual memory and address space than
you will use up before the program exits and have a good reason for
being sloppy.

F'rexample, if you need to construct some complicated and massively
inter-linked data structure that uses lots of little bits of dynamically
allocated memory, and you use this for everything that your program does,
then it may reasonable to decide that the complexity that doing the
deallocation correctly will add to your program is too much to justify
its inclusion.
If you do do this, you should document where memory that doesn't get
freed is allocated, to make life a little bit easier for whoever ends up
doing the work if it does end up needing to be re-used (on a different
complicated and massively inter-linked data structure) in a single run
of a larger program.


Cleaning up your malloc()d memory is a lot like avoiding goto: if
you think you need to break the rule, the first thing you should do is
re-think your design and try to find a way to do something that avoids
having to break the rule, but if you're sure that the best way to do
something does indeed involve breaking the rule, go ahead and break it
(but be sure to document what you did and why).

This is not homework; I have read section 7 of the FAQ.

I assume, then, that the answers to 7.24 and 7.25 didn't go into enough
detail to satisfy your curiousity?
(They relate to your questions, but only give yes/no answers without
any indication on where those answers might be relevant.)


dave
 
M

Mark A. Odell

Esteemed contributors to clc:

Thank you for all the responses.

Experiments 2 and 3 below are identical, except that
experiment 2 does not call free(), while experiment 3 does.

With such a trivial program, is it safe not to call free()?

It is always safe to call free in this situation, that is, if malloc
returns a valid pointer you may free it. If it returns NULL you may still
call free(NULL) with no ill effect.
Are there dangers in experiment 2 that experiment 3 avoids?

Not really, the host will reclaim all the memory used by your C program.
In what contexts does freeing memory become crucial?

When you start running low?
In what contexts does freeing memory not matter?

In example 2.
This is not homework; I have read section 7 of the FAQ.

Okay. See my edit in example 2.
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
char *h = malloc(30);
if (h == NULL) {
fprintf(stderr, "No memory allocation\n");
return EXIT_FAILURE;
}
 
S

Steve Zimmerman

################ Experiment 4 (malloc) #################

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

int main()
{
char *h;

h = malloc(30);
if (h == NULL)
fprintf(stderr, "No memory allocation\n");

printf("Successful memory allocation\n");

strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);

free(h);

return 0;
}

Output: Successful memory allocation
Malloc/Free Fields Forever

#######################################################

--Steve
 
A

Al Bowers

Steve said:
################ Experiment 4 (malloc) #################

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

int main()
{
char *h;

h = malloc(30);
if (h == NULL)
fprintf(stderr, "No memory allocation\n");

printf("Successful memory allocation\n");

strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);

free(h);

return 0;
}

Output: Successful memory allocation
Malloc/Free Fields Forever

You have a flaw in the logic. You correctly do an if statement to
detect a memory allocation failure. Then the program proceeds
as if there were a successful alloctaion. What would happen
in a allocation failure? The program will print "No memory
allocation". Then it will proceed and print "Successful
memory allocation". And then it will attemp to strcpy into
a null pointer will bad results. That's like doing
strcpy(NULL,"Malloc/Free Fields Forever"). One solution among many
is to exit the program after allocation failure. Another is to use
if-else.


/******************* Experiment 4.1 (malloc) ***************?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char *h;

h = malloc(30);
if (h == NULL)
fprintf(stderr, "No memory allocation\n");
else
{
printf("Successful memory allocation\n");
strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);
free(h);
}
return 0;
}

/******************* Experiment 4.2 (malloc) ***************?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char *h;

h = malloc(30);
if (h == NULL)
{
fprintf(stderr, "No memory allocation\n");
exit(EXIT_FAILURE);
}
printf("Successful memory allocation\n");
strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);
free(h);
return 0;
}
 
S

Steve Zimmerman

Steve said:
################ Experiment 4 (malloc) #################

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

int main()
{
char *h;

h = malloc(30);
if (h == NULL)
fprintf(stderr, "No memory allocation\n");

printf("Successful memory allocation\n");

strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);

free(h);

return 0;
}

Output: Successful memory allocation
Malloc/Free Fields Forever

#######################################################

--Steve

############# Experiment 5 (malloc) #####################

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

int main()
{
char *h;

strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);

return 0;
}

Output: Malloc/Free Fields Forever
Segmentation fault

##########################################################

Anyvon else wis a comment?

--Steve
 
A

Al Bowers

Steve said:
############# Experiment 5 (malloc) #####################

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

int main()
{
char *h;

strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);

return 0;
}

Output: Malloc/Free Fields Forever
Segmentation fault

##########################################################

Anyvon else wis a comment?

Yes!
Never tell a lie.
You are being immature and playing games. Maybe one day you
will grow up, but I will not invest money in the potential.
 
M

Mark A. Odell

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

int main()
{
char *h;

strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);

return 0;
}

Output: Malloc/Free Fields Forever
Segmentation fault

No @#$%. Look at your poorly named 'h' variable. What does it point to?
Something it shouldn't I'd bet. When you strcpy() to memory you don't own
your OS seg faults. On an unhosted embedded system the controller might
lockup.
 
A

Al Bowers

Mark said:
No @#$%. Look at your poorly named 'h' variable. What does it point to?
Something it shouldn't I'd bet. When you strcpy() to memory you don't own
your OS seg faults. On an unhosted embedded system the controller might
lockup.

It's a troll. The code was titled:
############# Experiment 5 (malloc) #####################
but there is no use of the malloc function.

Why would this code output "Malloc/Free Fields Forever" and then
seq fault? Every implementation that I use this code
would simply seg fault.
 
A

Arthur J. O'Dwyer

It's a troll. The code was titled:
############# Experiment 5 (malloc) #####################
but there is no use of the malloc function.

Why would this code output "Malloc/Free Fields Forever" and then
seg fault? Every implementation that I use this code
would simply seg fault.

Try MS-DOS with no optimization.
The fastest way to create object 'h' is probably to
push a zero onto the stack -- that effectively sets
'h' to NULL even though Steve's code doesn't.
Then write through 'h' to address 0. Then, at the
end of the program, check for wild null pointers
by "memcmp'ing" address 0. If the contents of address
0 have changed, print "Segmentation fault" and exit.

[This is how *one* implementation understands this
code. Other implementations, such as many *nix ones,
will indeed segfault more quickly. The code is, of
course, broken. (And while I wouldn't call Steve a
troll quite yet, he's definitely tending in that
direction.)]

-Arthur
 
S

Steve Zimmerman

Thank you for your post. Here are some simple programs
copyright (c) Al Bower, that are nice.



/******************* Experiment 4.1 (malloc) ***************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char *h;

h = malloc(30);
if (h == NULL)
fprintf(stderr, "No memory allocation\n");
else
{
printf("Successful memory allocation\n");
strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);
free(h);
}
return 0;
}

/******************* Experiment 4.2 (malloc) ***************?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
char *h;

h = malloc(30);
if (h == NULL)
{
fprintf(stderr, "No memory allocation\n");
exit(EXIT_FAILURE);
}
printf("Successful memory allocation\n");
strcpy(h, "Malloc/Free Fields Forever");
printf("%s\n", h);
free(h);
return 0;
}


Thank you, Al.

--Steve
 
D

David Gibson

[snip Mark A. Odell]
[snip]

It's a troll. The code was titled:
############# Experiment 5 (malloc) #####################
but there is no use of the malloc function.

Why would this code output "Malloc/Free Fields Forever" and then
seq fault? Every implementation that I use this code
would simply seg fault.
[snip]

It's a stack smash. If h is initialised to point into the stack,
just past itself, the strcpy() will trample main()s return address.

The program runs as expected (printing whatever), then, on return
from main(), *BOOM*

There seems to be a line missing from the code, just before the
strcpy(), though:

h = (char *)(&h + sizeof h);

(Linux, gcc, optimisation -O2)
 

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

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top