Re: memory allocation questions (newbie)

From: Stephen Ramsay (sramsay_at_uga.edu)
Date: 07/03/04


Date: Sat, 03 Jul 2004 00:59:44 GMT

On 2004-07-02, Mike Wahler <mkwahler@mkwahler.net> wrote:
> "Stephen Ramsay" <sramsay@uga.edu> wrote in message
> news:filFc.2028$Dv.1690@bignews2.bellsouth.net...
>> I'm wondering if someone can help me untangle some muddled thinking
>> about memory allocation in C. I'm writing my first non-trivial app in
>> C (and having a great time), but I'm finding it difficult to stamp out
>> memory leaks.
>>
>> I'm sure most of what I'm about to say is wrong. I'd really be very
>> grateful to know why.
>>
>> The use of malloc() in most of the books I've read make it sound pretty
>> straightforward.
>
> It is.

First, let me thank you for this wonderful reply. I was half expecting
a "read the faq" answer. Instead, I get a response that has really
helped me get several important things straight. To wit . . .

>> p = malloc(n * sizeof(int));
>
> Right. However many (including myself) prefer:
>
> p = malloc(n * sizeof *p);
>
> This means that if the type of 'p' later changes, it still works.

Ahah. I've seen this and never really understood what it meant.

Wait. I think I still don't. Now, if I understand correctly, "sizeof"
is an operator that takes a type name as it operand. So by saying
"sizeof *p," you're saying that you want the size to be equivalent to a
pointer-to-int. I think this means something like "a pointer that is
prepared to point to a memory location big enough to hold an int." In
either case, though, the lvalue of the expression is still a
pointer-to-int. I'm lost . . .

>> 0. Let's suppose that I allocate space for p,
>
> I assume you meant space for 'p' to point to. Space for 'p' itself
> is already allotted when you write:
>
> int *p;

Yes, I keep eliding this distinction . . .

>>but there are branches in
>> the program that won't actually use p. Do I need to free the memory at
>> every exit point?
>
> You should free it before the program terminates.
>
>>Or does the fact that this can happen indicate a bad
>> design on my part?
>
> Yes, I think having multiple exit points is not a good idea.
> (I suppose sometimes it might be unavoidable, but I strive
> to have only one exit point from any function, especially
> main().)
>
> Or are you terminating your program in ways other than returning
> from main(), e.g. calling 'exit()'. I'd only use that in
> extreme cases.

The example I'm thinking of is less convoluted than this, but I've spent
the last twenty minutes trying to think of an example and I think I've
convinced myself that my problem is Not Really A Problem.

> No, don't do it there. Do it in the same function where the memory
> was allocated. IOW consider whichever function did the allocation
> to 'own' that memory and take responsibility for freeing it.
>
> void func1(int *p)
> {
> /* do something with 'p' */
> }
>
> void func2(int *p)
> {
> /* do something with 'p' */
> }
>
> void func3(int *p)
> {
> /* do something with 'p' */
> }
>
> void foo(void)
> {
> int *p = malloc(100);
> func1();
> func2();
> func1();
> func3();
> free(p);
> }

Ah! Okay wait. I understand what you're saying. And if a funtion
returns a pointer to the caller, it becomes the caller's responsibility,
yes?

> Often functions will be conditionally called, or called
> within a loop, or indirectly through other functions. No
> point in trying to manually keep track of a pointer being
> passed around among them.
>
> Often I'll do all my allocation 'up front' in 'main()', then free the
> memory just before 'main()' returns.

Ah, that sounds so much easier than what I had been thinking about. But
this would have to include any malloc'd storage returned from functions
called by main()?

> It seems you think you need to do things the 'hard way'
> when you don't. :-)
>
>> My apologies if all of this seems too basic for this list.
>
> Not at all. Your questions were intelligent and well presented.
> Novices are very welcome here. But you might want to also
> check out alt.comp.lang.learn.c-c++, which is specifically geared
> toward the novice. But since it discusses both C and C++, when
> posting there, be sure to indicate which language you're asking about.

Thanks! I wasn't aware of the existence of this list. I'll post my
newbie questions there from now on and go back to lurking on this one.

> I suppose sooner or later you'll have occasion to use 'realloc()'.
> Be careful, and have fun! :-)

Good grief :(

I have to say, at the risk of starting a new thread, that I'm enjoying
all of this C business immensely. C was my first language, but I never
wrote anything serious in it because it was too hard, to confusing, too
error-prone, etc. I've been programming for years (on UNIX systems)
using Perl, Ruby, Java, and stuff like that. I like these languages a
lot, but it's really wonderful to come back to C after years of
experience writing programs in high-level languages. I have a much
better understanding of how computers work (above confusions aside) and
of software design, and now I find that the absolute freedom and
expressiveness of C is a real breath of fresh air. I wish I were faster
in it (I seem to spend a lot of time programming under seige with lint,
valgrind, and gdb close by), but it's a lot of fun to work things out
and try to get the most elegant solution possible. I wonder if many
people have had the experience of coming "back to C" from
ultra-high-level languages only to find that there's something really
cool about programming closer to the metal.

Thanks again,

Steve

-- 
Stephen Ramsay
Department of English
University of Georgia
web: http://cantor.english.uga.edu/


Relevant Pages

  • Re: C vs C++ in Embedded Systems?
    ... >>the garbage collection system be able to find every pointer that it needs ... >>ensuring that all pointer variables actually point to allocated memory. ... references, by definition, in these languages. ...
    (comp.arch.embedded)
  • Re: Three stupid C questions
    ... C and C++ are two different languages. ... (When a pointer in C is incremented, it points to the next object of whatever ... assigns b's current value into a, and if the result is zero, executes code. ... just paraphrase or type from memory unless your memory is a LOT better ...
    (comp.lang.c)
  • Re: C vs C++ in Embedded Systems?
    ... >>systems (for languages that don't mind having things move around at run ... the garbage collection system be able to find every pointer that it needs ... ensuring that all pointer variables actually point to allocated memory. ... True, that's why those systems make do with static allocations, and ...
    (comp.arch.embedded)
  • Re: OT:C/C++ Opinion Poll
    ... GC was to first remove the memory allocation/deallocation ... abstraction entirely in higher level languages. ... Removing references is what was meant. ... Even replacing all calls to free with a null pointer assignment ...
    (comp.arch.embedded)
  • Re: memory allocation questions (newbie)
    ... > memory leaks. ... I think having multiple exit points is not a good idea. ... IOW consider whichever function did the allocation ... when I pass a pointer to some allocated memory as ...
    (comp.lang.c)