comp.lang.ada
 help / color / mirror / Atom feed
* Re: access / freeing memory
  2002-07-16  0:52 access / freeing memory Jan Prazak
@ 2002-07-15 22:22 ` tmoran
  2002-07-16 13:54   ` Jan Prazak
  2002-07-23  6:15   ` Kevin Cline
  2002-07-18 18:22 ` chris.danx
  1 sibling, 2 replies; 15+ messages in thread
From: tmoran @ 2002-07-15 22:22 UTC (permalink / raw)


> head -> 1 -> 2 -> 3 -> null
>
>  head := null; (to delete all elements)
> or
>  head.next.next := null; (to delete the 3rd element)
>
> This would be a very bad programming technique in Pascal, because this
  Yes, you could do either of those assignment statements and yes you
would have a "memory leak" where the tail of the list would still be
occupying memory but would be inaccessible.  OTOH,
  This_List := head;
  ... various uses of This_List
  This_List := null;
would be OK since "head" would still be around to access the list,
and would probably be a good idea since it would prevent someone
fiddling with your list via This_List.  For instance if you have
changed to head->0->1->... you probably don't want someone going
directly to "1" via a left over This_List.

> The tutorial explains a similar procedure, called Unchecked_Deallocation,
  Given head->1->2... if you did an unchecked deallocation on "head"
it would free the memory occupied by "1" and also set "head" to null;
The 2->3->... part of the list would be allocated, but inaccessible.
What you need to do is a series of unchecked deallocations, say

  procedure Free is new Ada.Unchecked_Deallocation(...);

  procedure Free_List(x : List_Pointer) is
  begin
    if x.next /= null then Free_List(x.next);end if;
    Free(x);
  end Free_List;
  ...
  Free_List(head);

> but it's said that it's not recommended to use it (because some other
  Unchecked_Deallocation has that name because it's not checked.  Thus
you can really screw up, so it should be used carefully.  Some systems
have automatic garbage collection, but most Ada systems don't (problems
with real-time timing surprises, for instance).  You can get some
automatic deallocation going for you with careful placement of
"type ...  is access ..."  and especially with Storage_Pools.  But
mostly, with variable size array declarations and functions that can
return variable size things, you find much less need for access types
in Ada.  You can usually do stack, rather than heap, allocation which
buys automatic, safe, deallocation, and of course speed.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* access / freeing memory
@ 2002-07-16  0:52 Jan Prazak
  2002-07-15 22:22 ` tmoran
  2002-07-18 18:22 ` chris.danx
  0 siblings, 2 replies; 15+ messages in thread
From: Jan Prazak @ 2002-07-16  0:52 UTC (permalink / raw)


Hello,

I have finished reading one Ada tutorial (I won't say that I did
understand everything), but the section about "access" was not very
clearly explained.

Just imagine this simple situation:
I have a single-linked list, with a "head".

head -> 1 -> 2 -> 3 -> null

Is it really possible to say

 head := null; (to delete all elements)

or

 head.next.next := null; (to delete the 3rd element)

or similar things???

This would be a very bad programming technique in Pascal, because this
would create a "memory hole". There each element has to be "disposed" with
a procedure called "Dispose".

The tutorial explains a similar procedure, called Unchecked_Deallocation,
but it's said that it's not recommended to use it (because some other
access type could access that memory address (that's clear)).
So does the operating system take care of the deallocation?
And what about other OSs than Linux? Or has this to do with the Ada
compiler, which maintains the memory (de)allocation? (This would be more
logical.)

Thanks,
Jan




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-16 13:54   ` Jan Prazak
@ 2002-07-16 11:51     ` Fabien Garcia
  2002-07-16 22:59       ` Jan Prazak
  2002-07-16 15:42     ` Darren New
  1 sibling, 1 reply; 15+ messages in thread
From: Fabien Garcia @ 2002-07-16 11:51 UTC (permalink / raw)


Jan Prazak wrote:

> Let me know if I did understand this correctly: if I have a "head", which
> can access nodes (in a list), and I create some nodes and connect
> them,for instance:
> 
>   head -> 1 -> 2 -> 3 -> null
> 
> and if I do nothing (so the program will end), the operating system (or
> compiler???) does the deallocation automatically, just because "head" is
> a variable. It then goes, starting at head, through the whole list and
> frees the memory occupied by every node. Right?


In fact when your program terminates all the memory allocated to the 
process by the OS is freed. It's not a question of referenced
or unreferenced menory. The deallocation doesn't goes "down" your list
throught each node, it just erase everything.

Hope it will help a bit, sorry for not being able to answer to the 
others questions (I will be interested by others answer thought :) )

Fabien




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-15 22:22 ` tmoran
@ 2002-07-16 13:54   ` Jan Prazak
  2002-07-16 11:51     ` Fabien Garcia
  2002-07-16 15:42     ` Darren New
  2002-07-23  6:15   ` Kevin Cline
  1 sibling, 2 replies; 15+ messages in thread
From: Jan Prazak @ 2002-07-16 13:54 UTC (permalink / raw)


On Mon, 15 Jul 2002 21:22:51 -0100, tmoran wrote:

>   Yes, you could do either of those assignment statements and yes you
> would have a "memory leak" where the tail of the list would still be
> occupying memory but would be inaccessible.  OTOH,

Then I don't undertand why the tutorial doesn't mention it. It says
something like: "it's better to let the operating system manage it", but
I haven't ever heard of an operating system which can manage memory
(de)allocations (maybe Linux does it, but I have very little knowledge
of how Linux works). This "drastic" technique is also shown in a book
about programming I own (as an Ada example program, and *even* as a
Pascal version, without "Dispose" !). I have also read that access types
in Ada are more secure than pointers in other languages, but I don't see
any reason, both versions seem to be identical.

>   This_List := head;
>   ... various uses of This_List
>   This_List := null;
> would be OK since "head" would still be around to access the list, and
> would probably be a good idea since it would prevent someone fiddling
> with your list via This_List.  For instance if you have changed to
> head->0->1->... you probably don't want someone going directly to "1"
> via a left over This_List.

Let me know if I did understand this correctly: if I have a "head", which
can access nodes (in a list), and I create some nodes and connect
them,for instance:

  head -> 1 -> 2 -> 3 -> null

and if I do nothing (so the program will end), the operating system (or
compiler???) does the deallocation automatically, just because "head" is
a variable. It then goes, starting at head, through the whole list and
frees the memory occupied by every node. Right? If yes, why should I use
a second head, which points at the main head?
And how can I then access the nodes? With The_List.Head.all (first node)
etc.?

> What you need to do is a series of unchecked deallocations, say
> 
>   procedure Free is new Ada.Unchecked_Deallocation(...);
> 
>   procedure Free_List(x : List_Pointer) is begin
>     if x.next /= null then Free_List(x.next);end if; Free(x);
>   end Free_List;
>   ...
>   Free_List(head);

That's what I explained, it's neccessary to dispose every node in other
to delete the list. This recursive procedure is interesting, but it maybe
not good for large lists (because of memory usage).

>> but it's said that it's not recommended to use it (because some other
>   Unchecked_Deallocation has that name because it's not checked.  Thus
> you can really screw up, so it should be used carefully.  Some systems
> have automatic garbage collection, but most Ada systems don't (problems

What is an Ada system? You mean systems for which an Ada compiler is
available?

> with real-time timing surprises, for instance).  You can get some
> automatic deallocation going for you with careful placement of "type ...
>  is access ..."

Is this the thing I have explained above?

> and especially with Storage_Pools.  But mostly, with

What is a storage pool?

> variable size array declarations and functions that can return variable
> size things, you find much less need for access types in Ada.

I use pointers only for stacks (linked lists), trees etc.

> You can
> usually do stack, rather than heap, allocation which buys automatic,
> safe, deallocation, and of course speed.

What do you mean? Why should a FIFO be faster than a LIFO? Or do
you mean something else by this.

Thanks,
Jan




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-16 13:54   ` Jan Prazak
  2002-07-16 11:51     ` Fabien Garcia
@ 2002-07-16 15:42     ` Darren New
  2002-07-16 22:59       ` Jan Prazak
  2002-07-24  0:25       ` David Thompson
  1 sibling, 2 replies; 15+ messages in thread
From: Darren New @ 2002-07-16 15:42 UTC (permalink / raw)


Jan Prazak wrote:
> It says
> something like: "it's better to let the operating system manage it",

That would be called "garbage collection". Some (few, relatively unusual)
OSes implement it, some languages implement it, Ada allows it to be
implemented without requiring it to be implemented, so most Ada programs
don't expect it to be implemented.

On the other hand, if it's a short program that exits, and doesn't use a lot
of memory, it's "safer" to just leave the memory consumed than it is to try
to correctly dispose of it yourself. However, if the program runs for a long
time, you'll eventually run out of memory taking this tact.

> I haven't ever heard of an operating system which can manage memory
> (de)allocations (maybe Linux does it, but I have very little knowledge
> of how Linux works).

Nothing you're likely to have used. Mostly machines targetted at a specific
language, such as Smalltalk machines or Lisp machines will have it built
into the OS.

> I have also read that access types
> in Ada are more secure than pointers in other languages, but I don't see
> any reason, both versions seem to be identical.

Ada has rules that make it difficult for a pointer to point to incorrectly
allocated memory. In C, for example, you could point to a local variable and
return the pointer from the function. Ada disallows this unless you say you
really know what you're doing. Ada also allows you to "intercept"
allocations of memory, so you could do your own garbage collection with
enough effort.
The safety referred to, I think, has little to do with freeing unused
memory, tho.

> and if I do nothing (so the program will end), the operating system (or
> compiler???) does the deallocation automatically,

Yes. 

> just because "head" is
> a variable.

No. The operating system is keeping a similar list, except that instead of
1, 2, 3, it has "John's program", "Mary's compiler", "Fred's spreadsheed".
When Fred's spreadsheet calls the "exit" routine in the operating system,
the OS goes through the linked list to find Fred's spreadsheet and unlinks
the whole chunk of memory. The linked list inside Fred's program is all
inside the one giant chunk of memory that the OS allocated for it, so the OS
doesn't have to look at whether Fred's program thinks it's allocated or not.
It just tosses the whole chunk of memory. (That's a little simplified, but
you get the idea.)

If the OS gets this wrong, eventually memory fills up and the OS crashes,
which is one of the problems that kept Windows NT4 from running web servers
for more than a few months at a time, unlike Linux that lacked this bug and
would run for years.

> >> but it's said that it's not recommended to use it (because some other
> >   Unchecked_Deallocation has that name because it's not checked.  Thus
> > you can really screw up, so it should be used carefully.  Some systems
> > have automatic garbage collection, but most Ada systems don't (problems
> 
> What is an Ada system? You mean systems for which an Ada compiler is
> available?

Most Ada compilers will not generate code that will work right if you assume
there's garbage collection going on. In other words, in Ada, there's enough
information in the source code (and restrictions on how pointers and
addresses can be used) that the compiler *could* generate code that frees up
memory you aren't using. However, most Ada compilers don't generate such
code.
 
> > with real-time timing surprises, for instance).  You can get some
> > automatic deallocation going for you with careful placement of "type ...
> >  is access ..."
> 
> Is this the thing I have explained above?

No.

> > and especially with Storage_Pools.  But mostly, with
> What is a storage pool?

It's when the run-time system code that allocates memory calls a specific
procedure you wrote to find what memory to use. This allows you to write
code to keep track of that yourself, so you can write your own garbage
collector, etc.
 
> > You can
> > usually do stack, rather than heap, allocation which buys automatic,
> > safe, deallocation, and of course speed.
> 
> What do you mean? Why should a FIFO be faster than a LIFO? Or do
> you mean something else by this.

He means usually you can allocate a local variable with a
declare...begin...end (which allocates information on the CPU's stack)
rather than using "new" to allocate something and then specifically have to
free it up. He's basically comparing how you do variable-sized objects in
Ada to how you do variable-sized objects in C (which has no variable-sized
objects, so you have to use "new" (aka malloc) to allocate them) or Java
(which has all objects allocated from the heap, so can't put them on the
stack for efficiency).

You need to learn terms like "heap" and "stack" before a programming
tutorial in Ada is likely to make as much sense as it could. Languages where
the operation of the machine is completely and totally hidden from the user
(APL, BASIC, etc) don't need quite as many technical terms.

-- 
Darren New 
San Diego, CA, USA (PST). Cryptokeys on demand.
** http://home.san.rr.com/dnew/DNResume.html **
** http://images.fbrtech.com/dnew/ **

 Proud to live in a country where "fashionable" 
     is denim, "stone-washed" faded, with rips.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-16 15:42     ` Darren New
@ 2002-07-16 22:59       ` Jan Prazak
  2002-07-17  5:22         ` Simon Wright
  2002-07-24  0:25       ` David Thompson
  1 sibling, 1 reply; 15+ messages in thread
From: Jan Prazak @ 2002-07-16 22:59 UTC (permalink / raw)


On Tue, 16 Jul 2002 14:42:16 -0100, Darren New wrote:

> Fred's program thinks it's allocated or not. It just tosses the whole
> chunk of memory. (That's a little simplified, but you get the idea.)
> 

I will come back to this topic (see below).

>> What do you mean? Why should a FIFO be faster than a LIFO? Or do you
>> mean something else by this.
> 
> He means usually you can allocate a local variable with a
> declare...begin...end (which allocates information on the CPU's stack)
> rather than using "new" to allocate something and then specifically have
> to free it up. He's basically comparing how you do variable-sized
> objects in Ada to how you do variable-sized objects in C (which has no
> variable-sized objects, so you have to use "new" (aka malloc) to
> allocate them) or Java (which has all objects allocated from the heap,
> so can't put them on the stack for efficiency).

declare...begin...end is indeed a very useful feature, sometimes I use it
even when it's not neccessary (just to make the code more readable) (and
of course sometimes for exception handling), but declare..b..e will not
help me with pointers.

> You need to learn terms like "heap" and "stack" before a programming
> tutorial in Ada is likely to make as much sense as it could. Languages
> where the operation of the machine is completely and totally hidden from
> the user (APL, BASIC, etc) don't need quite as many technical terms.

Do you know some specific pages on the net, which would give me an
overview? (I don't want to go into details, so an overview or a small
introduction would be ok.)

Now let me resume the memory allocation. When a program starts, the OS
allocates a memory block (say 100 kb) for it, then the program starts to
generate some sort of stack with pointers, and breaks the 100 kb limit,
so the OS gives the program more memory, for instance 100 kb more. Then
the program doesn't destroy the stack, but it could say "head := null;"
or something, or resize the stack without destroying nodes etc.
Then the program ends, and the OS frees all the memory (200 kb),
maybe it goes through every byte and makes sure
that it's not somewhere "marked" as used (I don't know how memory
allocation works in detail.). Was this a good explanation, or am I still
wrong in some points?

Thanks,
Jan




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-16 11:51     ` Fabien Garcia
@ 2002-07-16 22:59       ` Jan Prazak
  0 siblings, 0 replies; 15+ messages in thread
From: Jan Prazak @ 2002-07-16 22:59 UTC (permalink / raw)


On Tue, 16 Jul 2002 10:51:20 -0100, Fabien Garcia wrote:


> 
> Hope it will help a bit, sorry for not being able to answer to the
> others questions (I will be interested by others answer thought :) )

Yes, it helped a bit. See also my other reply.




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-16 22:59       ` Jan Prazak
@ 2002-07-17  5:22         ` Simon Wright
  2002-07-17 21:36           ` Jan Prazak
  0 siblings, 1 reply; 15+ messages in thread
From: Simon Wright @ 2002-07-17  5:22 UTC (permalink / raw)


Jan Prazak <janp9@gmx.net> writes:

> Now let me resume the memory allocation. When a program starts, the
> OS allocates a memory block (say 100 kb) for it, then the program
> starts to generate some sort of stack with pointers, and breaks the
> 100 kb limit, so the OS gives the program more memory, for instance
> 100 kb more. Then the program doesn't destroy the stack, but it
> could say "head := null;" or something, or resize the stack without
> destroying nodes etc.  Then the program ends, and the OS frees all
> the memory (200 kb), maybe it goes through every byte and makes sure
> that it's not somewhere "marked" as used (I don't know how memory
> allocation works in detail.). Was this a good explanation, or am I
> still wrong in some points?

On a typical host OS like Windows or GNU/Linux, the OS makes memory
available to a process (execution of a program) on request, in chunks
(usually called "pages", size depends on CPU and OS; perhaps
2kB). When the process dies, the OS just deletes all the allocated
pages. No need to chase pointers; just delete the pages[1].

On the other hand, your typical real-time OS (like say VxWorks)
doesn't manage memory in this way. If your program never stops
(perhaps it's an engine control system), you don't have to worry about
what the OS would do if it did (though you still have to worry, a lot,
about memory leaks). But if you are running unit tests and you forget
to return memory at the end of your program, it's gone (until you
reboot and wipe the slate clean, which might not be such a bad idea at
that!).

[1] There is a lot of detail omitted here!



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-17  5:22         ` Simon Wright
@ 2002-07-17 21:36           ` Jan Prazak
  0 siblings, 0 replies; 15+ messages in thread
From: Jan Prazak @ 2002-07-17 21:36 UTC (permalink / raw)


On Wed, 17 Jul 2002 04:22:07 -0100, Simon Wright wrote:

> On the other hand, your typical real-time OS (like say VxWorks) doesn't
> manage memory in this way. If your program never stops (perhaps it's an

Never heard of VxWorks.

> [1] There is a lot of detail omitted here!

That's ok, you don't need to go into details.

Thanks,
Jan




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-16  0:52 access / freeing memory Jan Prazak
  2002-07-15 22:22 ` tmoran
@ 2002-07-18 18:22 ` chris.danx
  2002-07-19 13:32   ` Jan Prazak
  1 sibling, 1 reply; 15+ messages in thread
From: chris.danx @ 2002-07-18 18:22 UTC (permalink / raw)



"Jan Prazak" <janp9@gmx.net> wrote in message
news:pan.2002.07.15.23.51.51.725321.2066@gmx.net...
> Hello,
>
> I have finished reading one Ada tutorial (I won't say that I did
> understand everything), but the section about "access" was not very
> clearly explained.
>
> Just imagine this simple situation:
> I have a single-linked list, with a "head".
>
> head -> 1 -> 2 -> 3 -> null
>
> Is it really possible to say
>
>  head := null; (to delete all elements)
>
> or
>
>  head.next.next := null; (to delete the 3rd element)
>
> or similar things???

How do you know that head.next.next exists?


> This would be a very bad programming technique in Pascal, because this
> would create a "memory hole". There each element has to be "disposed" with
> a procedure called "Dispose".

See other ppls replies about unchecked_deallocation.

> The tutorial explains a similar procedure, called Unchecked_Deallocation,
> but it's said that it's not recommended to use it (because some other
> access type could access that memory address (that's clear)).
> So does the operating system take care of the deallocation?
> And what about other OSs than Linux? Or has this to do with the Ada
> compiler, which maintains the memory (de)allocation? (This would be more
> logical.)

Other ppls replies don't seem to be helping.  Let me try and clear a few
things up.  This is general and concerns memory management which may vary
between compilers, so this may not be what GNAT does, but you'll get the
idea!

Firstly, when you create an object via 'new' it is allocated and
initialised.  Usually a call to new will typically take memory from the
heap, this is an area of memory typically used for dynamic memory
management.  The heap is usually within your program, and the compiler will
insert code to manage it.

When you do head.next := null, what are you really doing?  You are saying
head.next is null, not that the node at head.next is, and since the node is
allocated on the heap, it still exists within the heap but is potentially no
longer accessable to the program.  If the compiler employs garbage
collection the node will be removed, but garbage collection isn't there yet,
so we'll neglect it and focus on non-garbage collected compilers (you can
still do this on GC collected compilers, it's probably not a good idea to
rely on the compiler to do things for you all the time).

How does the heap know it can use the memory again unless we tell it?  (the
heap doesn't know how many variables point to a particular item within in
it, only that some memory is associated with the item).  We use
unchecked_deallocation to tell the heap the memory isn't in use anymore.

Let's think about a singly linked list with the following setup.

- each node is a record containing an item and a pointer to the next item.

- each list is a record containing a pointer to the first item and a
variable recording the number of items in the list

- a position points to a node within the list (it could be a record, or
simply an access type).


If you want to deallocate a node at a given position, we need to first find
the node preceding the one at position.  Then we need to adjust that node we
found to skip over the node at position (what follows position?).  Now none
of the items in the list point to the node we wish to deallocated, but we
still know where it is in the heap since position records this (the position
is invisible to the programmer, who only knows it exists or it doesn't --
well in Ada anyway).  We can now deallocate the node at position by calling
unchecked_deallocation, and adjust the number of items in the list.  Then
position points to nothing (null) and the heap knows the memory is free for
reuse.

That's basically it.  It's worth noting that above you might get the
impression that the heap is a structure, but it doesn't have to be, and you
can still think of it as above with little loss regardless of how it's
actually done in practise.



HTH,
Chris

p.s. why do ppl mention things like Storage_Pools to newbies?  It only
confuses them and makes things harder!





^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
       [not found] <mailman.1026804243.16337.comp.lang.ada@ada.eu.org>
@ 2002-07-19  1:42 ` Robert A Duff
  0 siblings, 0 replies; 15+ messages in thread
From: Robert A Duff @ 2002-07-19  1:42 UTC (permalink / raw)


"Gautier direct_replies_not_read" <gautier_niouzes@hotmail.com> writes:

> The need to instanciate "Unchecked_Deallocation" and its name
> are there for the explained reasons. Personnally I find it a
> perverse detail in Ada's design, because it deliberately
> discourages using it, although a memory leak is not much better
> than misusing "Dispose" and surely far less easy to find.

True.  I think the original designers of Ada 83 imagined that garbage
collection would be commonly supported, so Unchecked_Deallocation would
be rarely needed (just like Unchecked_Conversion is rarely needed).  If
you believe that, the big ugly name makes sense.

- Bob



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-18 18:22 ` chris.danx
@ 2002-07-19 13:32   ` Jan Prazak
  2002-07-19 23:50     ` chris.danx
  0 siblings, 1 reply; 15+ messages in thread
From: Jan Prazak @ 2002-07-19 13:32 UTC (permalink / raw)


On Thu, 18 Jul 2002 17:22:38 -0100, chris.danx wrote:


>>  head.next.next := null; (to delete the 3rd element)
>>
>> or similar things???
> 
> How do you know that head.next.next exists?

Because the stack is head->1->2->3->null (it's just an example).

> Firstly, when you create an object via 'new' it is allocated and
> initialised.  Usually a call to new will typically take memory from the
> heap, this is an area of memory typically used for dynamic memory
> management.  The heap is usually within your program, and the compiler
> will insert code to manage it.

<...>

Thanks for this long description. I have already some experience with
pointers (in Pascal), so I have already found out how it works, but I
didn't know anything about heap (I didn't even know what it is, I thought
of some kind of a stack), so now I'm a bit wiser.

> p.s. why do ppl mention things like Storage_Pools to newbies?  It only
> confuses them and makes things harder!

Yes, that was really confusing...

BTW: I have read that Modula-3 has a fully functionable garbage
collection, and M3 is also free available, but I think I will continue
using Ada and have a look at M3 later. To all: does someone know where to
find a brief comparison between Ada95 and M3?

Jan




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-19 13:32   ` Jan Prazak
@ 2002-07-19 23:50     ` chris.danx
  0 siblings, 0 replies; 15+ messages in thread
From: chris.danx @ 2002-07-19 23:50 UTC (permalink / raw)



"Jan Prazak" <janp9@gmx.net> wrote in message
news:pan.2002.07.19.11.55.21.740237.1504@gmx.net...

> Thanks for this long description. I have already some experience with
> pointers (in Pascal), so I have already found out how it works, but I
> didn't know anything about heap (I didn't even know what it is, I thought
> of some kind of a stack), so now I'm a bit wiser.

I made the point that the heap might not be a real entity (that depends on
the compiler), but it's still a good conceptual model to have in your head
when thinking about dynamic memory in normal use.  Once you get the model,
learning the syntax and semantics is easier.






^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-15 22:22 ` tmoran
  2002-07-16 13:54   ` Jan Prazak
@ 2002-07-23  6:15   ` Kevin Cline
  1 sibling, 0 replies; 15+ messages in thread
From: Kevin Cline @ 2002-07-23  6:15 UTC (permalink / raw)


tmoran@acm.org wrote in message news:<%WHY8.1173$tt5.52024504@newssvr13.news.prodigy.com>...
> > head -> 1 -> 2 -> 3 -> null
> >
> >  head := null; (to delete all elements)
> > or
> >  head.next.next := null; (to delete the 3rd element)
> >
> > This would be a very bad programming technique in Pascal, because this
>   Yes, you could do either of those assignment statements and yes you
> would have a "memory leak" where the tail of the list would still be
> occupying memory but would be inaccessible.  OTOH,
>   This_List := head;
>   ... various uses of This_List
>   This_List := null;
> would be OK since "head" would still be around to access the list,
> and would probably be a good idea since it would prevent someone
> fiddling with your list via This_List.  For instance if you have
> changed to head->0->1->... you probably don't want someone going
> directly to "1" via a left over This_List.
> 
> > The tutorial explains a similar procedure, called Unchecked_Deallocation,
>   Given head->1->2... if you did an unchecked deallocation on "head"
> it would free the memory occupied by "1" and also set "head" to null;
> The 2->3->... part of the list would be allocated, but inaccessible.
> What you need to do is a series of unchecked deallocations, say
> 
>   procedure Free is new Ada.Unchecked_Deallocation(...);
> 
>   procedure Free_List(x : List_Pointer) is
>   begin
>     if x.next /= null then Free_List(x.next);end if;
>     Free(x);
>   end Free_List;
>   ...
>   Free_List(head);
> 
> > but it's said that it's not recommended to use it (because some other
>   Unchecked_Deallocation has that name because it's not checked.  Thus
> you can really screw up, so it should be used carefully.  Some systems
> have automatic garbage collection, but most Ada systems don't (problems
> with real-time timing surprises, for instance).  You can get some
> automatic deallocation going for you with careful placement of
> "type ...  is access ..."  and especially with Storage_Pools.  But
> mostly, with variable size array declarations and functions that can
> return variable size things, you find much less need for access types
> in Ada.  You can usually do stack, rather than heap, allocation which
> buys automatic, safe, deallocation, and of course speed.
 
I find statements like this rather naive.  It implies that Ada programmers
have little need for any data structure more complex than an array, 
and I don't understand why this belief seems to be so widely promulgated.
Although Ada supports arrays particularly well, for most problems 
use of associative containers leads to a simpler solution.

It's unfortunate that the Ada community never adopted a high-quality
standard container library.  The lack of such a library increases
the start-up cost of an Ada project -- libraries have to be located
and evaluated or written anew.  The result is that things that should
be easy become difficult, and developers who try Ada become frustrated
and move on.



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: access / freeing memory
  2002-07-16 15:42     ` Darren New
  2002-07-16 22:59       ` Jan Prazak
@ 2002-07-24  0:25       ` David Thompson
  1 sibling, 0 replies; 15+ messages in thread
From: David Thompson @ 2002-07-24  0:25 UTC (permalink / raw)


A slight clarification:

Darren New <dnew@san.rr.com> wrote :
(other good stuff about memory allocation/management snipped)
...
> > > You can
> > > usually do stack, rather than heap, allocation which buys automatic,
> > > safe, deallocation, and of course speed.
...
> He means usually you can allocate a local variable with a
> declare...begin...end (which allocates information on the CPU's stack)
> rather than using "new" to allocate something and then specifically have to
> free it up. He's basically comparing how you do variable-sized objects in
> Ada to how you do variable-sized objects in C (which has no variable-sized
> objects, so you have to use "new" (aka malloc) to allocate them) or Java
> (which has all objects allocated from the heap, so can't put them on the
> stack for efficiency).
>
In C you have malloc (and calloc and realloc) which only allocates
raw memory (and for calloc initializes it to all zero bits, which is
often but not required to be a useful value such as a zero integer,
null pointer, etc.), and free which deallocates it.  Some implementations
also have alloca(), which allocates variable-sized space on the stack
in the current function's (subprogram's) frame, but this is nonstandard.

In C++ you can still use the C forms, but also have 'new' which
allocates memory _and runs a (possibly trivial) constructor for the
new object's type_ and 'delete' which _runs the destructor and_
frees the underlying memory.  (Actually you also have placement
new which _only_ runs the constructor, using memory you have
allocated by other means, but that's just confusing the issue.)
The memory allocation and deallocation part of 'new' and 'delete'
typically is actually done by malloc and free, but this is not required.

And in C99 (and perhaps in some future C++), AFAIK not yet
implemented outside gcc (where it was already an extension),
you can have local (stack) _arrays_ with runtime/nonstatic sizes,
called logically enough Variable Length Arrays.  But not similarly
for the other things Ada discriminated and/or private types can do.

In the Java spec it is certainly true that all objects (of nonprimitive
types) are on the heap.  However, for an object that is actually
used only locally within one function, it is my understanding that
a decent "real" (native) compiler can actually put it on the stack,
which the resulting efficiency gains.  I'm not sure if it's practical
for a JIT to do the same, but it's presumably at least permitted.

--
- David.Thompson 1 now at worldnet.att.net






^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2002-07-24  0:25 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-16  0:52 access / freeing memory Jan Prazak
2002-07-15 22:22 ` tmoran
2002-07-16 13:54   ` Jan Prazak
2002-07-16 11:51     ` Fabien Garcia
2002-07-16 22:59       ` Jan Prazak
2002-07-16 15:42     ` Darren New
2002-07-16 22:59       ` Jan Prazak
2002-07-17  5:22         ` Simon Wright
2002-07-17 21:36           ` Jan Prazak
2002-07-24  0:25       ` David Thompson
2002-07-23  6:15   ` Kevin Cline
2002-07-18 18:22 ` chris.danx
2002-07-19 13:32   ` Jan Prazak
2002-07-19 23:50     ` chris.danx
     [not found] <mailman.1026804243.16337.comp.lang.ada@ada.eu.org>
2002-07-19  1:42 ` Robert A Duff

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox