comp.lang.ada
 help / color / mirror / Atom feed
* Memory_Management
@ 2005-04-19  1:39 Bini
  2005-04-19  9:18 ` Memory_Management Duncan Sands
  0 siblings, 1 reply; 23+ messages in thread
From: Bini @ 2005-04-19  1:39 UTC (permalink / raw)


with Ada.Finalization;
with Memory_Management;

package Pkg is
	My_Pool : Memory_Management.User_Pool(Size => 500);

	type My_Int is access Integer;
	for My_Int'Storage_Pool use My_Pool;

	type My_Data is new Ada.Finalization.Controlled with record
		Value	: My_Int;
	end record;

	procedure Initialize(Data : in out My_Data);
	procedure Finalize(Data : in out My_Data);
end Pkg;

with Ada.Unchecked_Deallocation;

package body Pkg is
	.
        .
	procedure Finalize(Data : in out My_Data) is
	begin
		Free(Data.Value);
	end Finalize;
        .
        .
end Pkg;

with Ada.Text_IO;
with Ada.Finalization;
with Pkg;
procedure Fun is
	package TIO renames Ada.Text_IO;
	package AF renames Ada.Finalization;

	I1, I2	: Pkg.My_Data;
	I3	: Pkg.My_Int;
begin
	I1 := (AF.Controlled with Value => new Integer'(123));
	TIO.Put_Line(I1.Value.all'Img);
	I2 := (AF.Controlled with Value => new Integer'(456));
	TIO.Put_Line(I2.Value.all'Img);
	I3 := new Integer'(789);
	TIO.Put_Line(I3.all'Img);
end Fun;


===> I write some test code with Memory_Management
package(http://www.adapower.com/index.php?Command=Class&ClassID=Advanced&CID=222)
from Anh Vo

fun.exe result is

0
0
789

and I1.Value'Address and I2.Value'Address is equal.
I can not understand this result.
My English is poor.
Thank You.



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

* Re: Memory_Management
  2005-04-19  1:39 Memory_Management Bini
@ 2005-04-19  9:18 ` Duncan Sands
  2005-04-20  1:06   ` Memory_Management Bini
  0 siblings, 1 reply; 23+ messages in thread
From: Duncan Sands @ 2005-04-19  9:18 UTC (permalink / raw)
  To: Bini; +Cc: comp.lang.ada

Hi Bini, maybe what is happening is this:

> 	I1 := (AF.Controlled with Value => new Integer'(123));

here the right-hand-side (RHS) is an object of My_Data type.
You assign it to I1, another object of My_Data type.  After
the assignment, RHS is finalized.  This frees the memory - the
same memory I1.Value is pointing to.  In detail:

(0) Memory is allocated to hold the integer 123.  A pointer
to the memory is in RHS.Value.
(1) a bit-wise copy is made of RHS onto I1.  I1.Value points
to the integer.
(2) Adjust is called on I1.  Since you don't seem to have
defined Adjust, this does nothing.
(3) Finalize is called on RHS.  This frees the memory holding
123.  Now I1.Value is pointing to freed memory.

You then look at I1.Value.all, which could be anything.

You need to define Adjust.

All the best,

Duncan.




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

* Re: Memory_Management
@ 2005-04-19 20:30 Anh Vo
  0 siblings, 0 replies; 23+ messages in thread
From: Anh Vo @ 2005-04-19 20:30 UTC (permalink / raw)
  To: baldrick, fracttcarf; +Cc: comp.lang.ada

Or may be the intention was to allocate the memory for component Value of I1 and I2. If this is the case, allocate and assign to Value as shown below. Then, the results should be printed out as expected.

     I1.Value := new Integer' (123);

     I2.Value := new Integer' (456);

By the way, I am the author of the Memory Management. I do have a new and improved version of Memory Management. In addition, I have change the name to Storage Pool Handler. If any one is interested, please let me know with an private email. I will sent it to you.

AV

>>> Duncan Sands <baldrick@free.fr> 04/19/05 2:18 AM >>>
Hi Bini, maybe what is happening is this:

> 	I1 := (AF.Controlled with Value => new Integer'(123));

here the right-hand-side (RHS) is an object of My_Data type.
You assign it to I1, another object of My_Data type.  After
the assignment, RHS is finalized.  This frees the memory - the
same memory I1.Value is pointing to.  In detail:

(0) Memory is allocated to hold the integer 123.  A pointer
to the memory is in RHS.Value.
(1) a bit-wise copy is made of RHS onto I1.  I1.Value points
to the integer.
(2) Adjust is called on I1.  Since you don't seem to have
defined Adjust, this does nothing.
(3) Finalize is called on RHS.  This frees the memory holding
123.  Now I1.Value is pointing to freed memory.

You then look at I1.Value.all, which could be anything.

You need to define Adjust.






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

* Re: Memory_Management
  2005-04-19  9:18 ` Memory_Management Duncan Sands
@ 2005-04-20  1:06   ` Bini
  0 siblings, 0 replies; 23+ messages in thread
From: Bini @ 2005-04-20  1:06 UTC (permalink / raw)


Duncan Sands <baldrick@free.fr> wrote in message news:<mailman.47.1113902314.24457.comp.lang.ada@ada-france.org>...
> Hi Bini, maybe what is happening is this:
> 
> > 	I1 := (AF.Controlled with Value => new Integer'(123));
> 
> here the right-hand-side (RHS) is an object of My_Data type.
> You assign it to I1, another object of My_Data type.  After
> the assignment, RHS is finalized.  This frees the memory - the
> same memory I1.Value is pointing to.  In detail:
> 
> (0) Memory is allocated to hold the integer 123.  A pointer
> to the memory is in RHS.Value.
> (1) a bit-wise copy is made of RHS onto I1.  I1.Value points
> to the integer.
> (2) Adjust is called on I1.  Since you don't seem to have
> defined Adjust, this does nothing.
> (3) Finalize is called on RHS.  This frees the memory holding
> 123.  Now I1.Value is pointing to freed memory.
> 
> You then look at I1.Value.all, which could be anything.
> 
> You need to define Adjust.
> 
> All the best,
> 
> Duncan.

Ok. I understand. Thank you very much.



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

* memory management
@ 2005-05-26  0:57 alex goldman
  2005-05-26  2:14 ` David C. Hoos, Sr.
  2005-05-26 12:10 ` Robert A Duff
  0 siblings, 2 replies; 23+ messages in thread
From: alex goldman @ 2005-05-26  0:57 UTC (permalink / raw)


As I understood from reading the Ada tutorial for C/C++ programmers,
"access" is essentially like C++ smart pointer, except that you don't need
to do anything to dereference it.

How will the following work:

Record A contains "access" to record B; 
record B contains "access" to record A.

If I create an instance of one of them with "new", will it be destroyed when
"access" to it goes out of scope?




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

* Re: memory management
  2005-05-26  0:57 memory management alex goldman
@ 2005-05-26  2:14 ` David C. Hoos, Sr.
  2005-05-26 13:21   ` Steve
  2005-05-27 14:33   ` Martin Krischik
  2005-05-26 12:10 ` Robert A Duff
  1 sibling, 2 replies; 23+ messages in thread
From: David C. Hoos, Sr. @ 2005-05-26  2:14 UTC (permalink / raw)
  To: alex goldman; +Cc: comp.lang.ada

There is no automatic deallocation of memory when an
access object goes out of scope, unless the
designated object is a controlled type.

----- Original Message ----- 
From: "alex goldman" <hello@spamm.er>
Newsgroups: comp.lang.ada
To: <comp.lang.ada@ada-france.org>
Sent: May 25, 2005 7:57 PM
Subject: memory management


> As I understood from reading the Ada tutorial for C/C++ programmers,
> "access" is essentially like C++ smart pointer, except that you don't need
> to do anything to dereference it.
> 
> How will the following work:
> 
> Record A contains "access" to record B; 
> record B contains "access" to record A.
> 
> If I create an instance of one of them with "new", will it be destroyed when
> "access" to it goes out of scope?
> 
> _______________________________________________
> comp.lang.ada mailing list
> comp.lang.ada@ada-france.org
> http://www.ada-france.org/mailman/listinfo/comp.lang.ada
> 
>



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

* Re: memory management
  2005-05-26  0:57 memory management alex goldman
  2005-05-26  2:14 ` David C. Hoos, Sr.
@ 2005-05-26 12:10 ` Robert A Duff
  2005-05-27 14:31   ` Martin Krischik
  1 sibling, 1 reply; 23+ messages in thread
From: Robert A Duff @ 2005-05-26 12:10 UTC (permalink / raw)


alex goldman <hello@spamm.er> writes:

> As I understood from reading the Ada tutorial for C/C++ programmers,
> "access" is essentially like C++ smart pointer,

No, Ada access types are just pointers -- no "smarts".
To make something like smart pointers, you can use
controlled types.

>... except that you don't need
> to do anything to dereference it.

Dereference of access types uses the syntax ".all", but it's allowed to
be implicit in most contexts (for example, X.Y means X.all.Y, if X
is an access value (pointer)).

> How will the following work:
> 
> Record A contains "access" to record B; 
> record B contains "access" to record A.
> 
> If I create an instance of one of them with "new", will it be destroyed when
> "access" to it goes out of scope?

No.

- Bob



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

* Re: memory management
  2005-05-26  2:14 ` David C. Hoos, Sr.
@ 2005-05-26 13:21   ` Steve
  2005-05-26 18:40     ` alex goldman
  2005-05-26 18:47     ` Pascal Obry
  2005-05-27 14:33   ` Martin Krischik
  1 sibling, 2 replies; 23+ messages in thread
From: Steve @ 2005-05-26 13:21 UTC (permalink / raw)


Unless the access type goes out of scope in which case the memory is 
automatically recovered (memory pools and all).

Steve
(The Duck)

"David C. Hoos, Sr." <david.c.hoos.sr@ada95.com> wrote in message 
news:mailman.131.1117073739.24457.comp.lang.ada@ada-france.org...
> There is no automatic deallocation of memory when an
> access object goes out of scope, unless the
> designated object is a controlled type.
>
> ----- Original Message ----- 
> From: "alex goldman" <hello@spamm.er>
> Newsgroups: comp.lang.ada
> To: <comp.lang.ada@ada-france.org>
> Sent: May 25, 2005 7:57 PM
> Subject: memory management
>
>
>> As I understood from reading the Ada tutorial for C/C++ programmers,
>> "access" is essentially like C++ smart pointer, except that you don't 
>> need
>> to do anything to dereference it.
>>
>> How will the following work:
>>
>> Record A contains "access" to record B; record B contains "access" to 
>> record A.
>>
>> If I create an instance of one of them with "new", will it be destroyed 
>> when
>> "access" to it goes out of scope?
>>
>> _______________________________________________
>> comp.lang.ada mailing list
>> comp.lang.ada@ada-france.org
>> http://www.ada-france.org/mailman/listinfo/comp.lang.ada
>> 




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

* Re: memory management
  2005-05-26 13:21   ` Steve
@ 2005-05-26 18:40     ` alex goldman
  2005-05-28  2:13       ` Steve
  2005-05-26 18:47     ` Pascal Obry
  1 sibling, 1 reply; 23+ messages in thread
From: alex goldman @ 2005-05-26 18:40 UTC (permalink / raw)


Steve wrote:

> Unless the access type goes out of scope in which case the memory is
> automatically recovered (memory pools and all).
> 
> Steve
> (The Duck)

I can't unify this statement with what the other two people wrote.



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

* Re: memory management
  2005-05-26 13:21   ` Steve
  2005-05-26 18:40     ` alex goldman
@ 2005-05-26 18:47     ` Pascal Obry
  1 sibling, 0 replies; 23+ messages in thread
From: Pascal Obry @ 2005-05-26 18:47 UTC (permalink / raw)



"Steve" <nospam_steved94@comcast.net> writes:

> Unless the access type goes out of scope in which case the memory is 
> automatically recovered (memory pools and all).

And you do not use the default memory pool, right ?

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|              http://www.obry.net
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver wwwkeys.pgp.net --recv-key C1082595



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

* Re: memory management
  2005-05-26 12:10 ` Robert A Duff
@ 2005-05-27 14:31   ` Martin Krischik
  2005-05-28 11:44     ` Robert A Duff
  0 siblings, 1 reply; 23+ messages in thread
From: Martin Krischik @ 2005-05-27 14:31 UTC (permalink / raw)


Robert A Duff wrote:

> alex goldman <hello@spamm.er> writes:
> 
>> As I understood from reading the Ada tutorial for C/C++ programmers,
>> "access" is essentially like C++ smart pointer,
> 
> No, Ada access types are just pointers -- no "smarts".
> To make something like smart pointers, you can use
> controlled types.

No again - any paricular Ada implementation is free to implement access
types as they see fit. With GNAT an access may consist of an pointer to the
data and a pointer to a dope vector:

http://en.wikipedia.org/wiki/Dope_vector

Remeber that an Ada compiler may also implement garbage collection.

Martin
-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com




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

* Re: memory management
  2005-05-26  2:14 ` David C. Hoos, Sr.
  2005-05-26 13:21   ` Steve
@ 2005-05-27 14:33   ` Martin Krischik
  1 sibling, 0 replies; 23+ messages in thread
From: Martin Krischik @ 2005-05-27 14:33 UTC (permalink / raw)


David C. Hoos, Sr. wrote:

> There is no automatic deallocation of memory when an
> access object goes out of scope, unless the
> designated object is a controlled type.

Ada compiler are allowed to implement garbage collection - so they may be
automatic deallocation. And indeed there is in some setup (JGNAT, A# and
AdaCL).

Martin

-- 
mailto://krischik@users.sourceforge.net
Ada programming at: http://ada.krischik.com




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

* Re: memory management
  2005-05-26 18:40     ` alex goldman
@ 2005-05-28  2:13       ` Steve
  2005-05-28  5:19         ` Jeffrey Carter
  0 siblings, 1 reply; 23+ messages in thread
From: Steve @ 2005-05-28  2:13 UTC (permalink / raw)


"alex goldman" <hello@spamm.er> wrote in message 
news:2001872.III9f6vnvx@yahoo.com...
> Steve wrote:
>
>> Unless the access type goes out of scope in which case the memory is
>> automatically recovered (memory pools and all).
>>
>> Steve
>> (The Duck)
>
> I can't unify this statement with what the other two people wrote.

Ignore my comment.

It involves Storage Pools, which is a rather complicated subject when you're 
just getting started.

For 99% of applications you never need to deal with them.

Steve
(The Duck)





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

* Re: memory management
  2005-05-28  2:13       ` Steve
@ 2005-05-28  5:19         ` Jeffrey Carter
  2005-05-28 14:48           ` Steve
  0 siblings, 1 reply; 23+ messages in thread
From: Jeffrey Carter @ 2005-05-28  5:19 UTC (permalink / raw)


Steve wrote:
> 
> For 99% of applications you never need to deal with them.

Of course not. That's approximately the percentage of applications that 
don't need access types.

-- 
Jeff Carter
"Ditto, you provincial putz?"
Blazing Saddles
86



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

* Re: memory management
  2005-05-27 14:31   ` Martin Krischik
@ 2005-05-28 11:44     ` Robert A Duff
  2005-05-28 13:03       ` Simon Wright
                         ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Robert A Duff @ 2005-05-28 11:44 UTC (permalink / raw)


Martin Krischik <krischik@users.sourceforge.net> writes:

> Robert A Duff wrote:
> 
> > alex goldman <hello@spamm.er> writes:
> > 
> >> As I understood from reading the Ada tutorial for C/C++ programmers,
> >> "access" is essentially like C++ smart pointer,
> > 
> > No, Ada access types are just pointers -- no "smarts".
> > To make something like smart pointers, you can use
> > controlled types.
> 
> No again - any paricular Ada implementation is free to implement access
> types as they see fit. With GNAT an access may consist of an pointer to the
> data and a pointer to a dope vector:

That's what I call a "fat pointer".  Still just a pointer (as opposed to
a smart pointer).

When I say "pointer", I don't mean it has to be implemented as a single
machine address.  It could be an offset from some known base address, an
index into an array, or (as you say) a fat pointer -- among other
things.

The same is true of pointers in C and C++ -- an implementation is free
to implement pointers as something other than a machine address.  In
fact, if a C compiler wishes to check array bounds, it pretty much *has*
to use fat pointers.  I know of one C compiler that did just that.  My
point is that "pointer" is not synonymous with "single machine address",
even in C.

By the way, I believe the fat pointers used by GNAT are an option --
there's some way to tell it to use thin pointers for access-to-array.
GNAT uses fat pointers (by default) only when the designated type is an
array, or when the designated type is unknown to the compiler.
Access-to-record, which is far more common, uses thin pointers.
I don't know of any Ada implementation besides GNAT that uses
fat pointers at all.

> http://en.wikipedia.org/wiki/Dope_vector

> Remeber that an Ada compiler may also implement garbage collection.

Yes.  That would typically *not* involve smart pointers.

- Bob



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

* Re: memory management
  2005-05-28 11:44     ` Robert A Duff
@ 2005-05-28 13:03       ` Simon Wright
  2005-05-31 12:04         ` Robert A Duff
  2005-06-02 15:42       ` Thomas Maier-Komor
  2005-06-03  1:41       ` Steve
  2 siblings, 1 reply; 23+ messages in thread
From: Simon Wright @ 2005-05-28 13:03 UTC (permalink / raw)


Robert A Duff <bobduff@shell01.TheWorld.com> writes:

> By the way, I believe the fat pointers used by GNAT are an option --
> there's some way to tell it to use thin pointers for
> access-to-array.  GNAT uses fat pointers (by default) only when the
> designated type is an array, or when the designated type is unknown
> to the compiler.  Access-to-record, which is far more common, uses
> thin pointers.  I don't know of any Ada implementation besides GNAT
> that uses fat pointers at all.

I think that it uses fat pointers when the type concerned is
indefinite.

You can make it use thin pointers by specifying the 'Size of the
pointer (to be 32) or, I'm pretty sure, by pragma Convention (C); I've
sent classwide pointers via Xt client_data values using one of these
techniques.



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

* Re: memory management
  2005-05-28  5:19         ` Jeffrey Carter
@ 2005-05-28 14:48           ` Steve
  0 siblings, 0 replies; 23+ messages in thread
From: Steve @ 2005-05-28 14:48 UTC (permalink / raw)


"Jeffrey Carter" <spam@spam.com> wrote in message 
news:0cTle.1206$s64.205@newsread1.news.pas.earthlink.net...
> Steve wrote:
>>
>> For 99% of applications you never need to deal with them.
>
> Of course not. That's approximately the percentage of applications that 
> don't need access types.
>

It is kind of hard to dynamically create objects whos type is determined at 
run time without them.

For example I wrote a data collection application that uses an abstract 
"scanner" type for data collection.  When the system initializes an instance 
of a class derived from scanner is created and passed to the data collection 
task.  The type of scanner created is selected by a user parameter.

It's kind of hard to do this without access types.  So, while I agree that 
access types are needed for a lot fewer cases in Ada than other languages, I 
disagree with the statement that a high percentage of applications don't 
need them.

Steve
(The Duck)

> -- 
> Jeff Carter
> "Ditto, you provincial putz?"
> Blazing Saddles
> 86 





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

* Re: memory management
  2005-05-28 13:03       ` Simon Wright
@ 2005-05-31 12:04         ` Robert A Duff
  0 siblings, 0 replies; 23+ messages in thread
From: Robert A Duff @ 2005-05-31 12:04 UTC (permalink / raw)


Simon Wright <simon@pushface.org> writes:

> Robert A Duff <bobduff@shell01.TheWorld.com> writes:
> 
> > By the way, I believe the fat pointers used by GNAT are an option --
> > there's some way to tell it to use thin pointers for
> > access-to-array.  GNAT uses fat pointers (by default) only when the
> > designated type is an array, or when the designated type is unknown
> > to the compiler.  Access-to-record, which is far more common, uses
> > thin pointers.  I don't know of any Ada implementation besides GNAT
> > that uses fat pointers at all.
> 
> I think that it uses fat pointers when the type concerned is
> indefinite.

I don't think so -- I think it's only for indefinite *arrays*
(or unknown types).  There's really no advantage in fat pointers
for records, unless tags/discrims are separated out, which GNAT
does not do.  (Nor does any other compiler I know of.)

> You can make it use thin pointers by specifying the 'Size of the
> pointer (to be 32) or, I'm pretty sure, by pragma Convention (C); I've
> sent classwide pointers via Xt client_data values using one of these
> techniques.

Yes, I think that's right.

- Bob



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

* Re: memory management
  2005-05-28 11:44     ` Robert A Duff
  2005-05-28 13:03       ` Simon Wright
@ 2005-06-02 15:42       ` Thomas Maier-Komor
  2005-06-02 17:05         ` Robert A Duff
  2005-06-03  1:41       ` Steve
  2 siblings, 1 reply; 23+ messages in thread
From: Thomas Maier-Komor @ 2005-06-02 15:42 UTC (permalink / raw)


Robert A Duff wrote:
> The same is true of pointers in C and C++ -- an implementation is free
> to implement pointers as something other than a machine address.  In
> fact, if a C compiler wishes to check array bounds, it pretty much *has*
> to use fat pointers.  I know of one C compiler that did just that.  My
> point is that "pointer" is not synonymous with "single machine address",
> even in C.
> 

That's definetly an interesting implementation variant for the C
language. Could you tell us, which compiler did this? Has this been
documented anywhere?

TIA,

Tom



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

* Re: memory management
  2005-06-02 15:42       ` Thomas Maier-Komor
@ 2005-06-02 17:05         ` Robert A Duff
  0 siblings, 0 replies; 23+ messages in thread
From: Robert A Duff @ 2005-06-02 17:05 UTC (permalink / raw)


Thomas Maier-Komor <maierkom@lpr.no-spam.e-technik.tu-muenchen.de> writes:

> Robert A Duff wrote:
> > The same is true of pointers in C and C++ -- an implementation is free
> > to implement pointers as something other than a machine address.  In
> > fact, if a C compiler wishes to check array bounds, it pretty much *has*
> > to use fat pointers.  I know of one C compiler that did just that.  My
> > point is that "pointer" is not synonymous with "single machine address",
> > even in C.
> >
> 
> That's definetly an interesting implementation variant for the C
> language. Could you tell us, which compiler did this? Has this been
> documented anywhere?

No, sorry, but I can't remember the name of the company or the product.
I think they went out of business about 10 years ago.  Their compiler
was intended for testing -- detecting array indices out of bounds.

Here's how to do it: allocate one word of dope before each array,
to store the length of the array.  Represent each C pointer as
a fat pointer: pointer to the dope, and pointer to the array
element.  Treat non-array objects like one-element arrays.
Then on each pointer dereference, check that the element pointer is
between the start and end of the array.

Ada compilers can do all this *much* more efficiently.
Ada does not need fat pointers.  GNAT uses them, but
only in rare cases.

- Bob



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

* Re: memory management
  2005-05-28 11:44     ` Robert A Duff
  2005-05-28 13:03       ` Simon Wright
  2005-06-02 15:42       ` Thomas Maier-Komor
@ 2005-06-03  1:41       ` Steve
  2005-06-03 10:12         ` alex goldman
  2005-06-13  4:01         ` Dave Thompson
  2 siblings, 2 replies; 23+ messages in thread
From: Steve @ 2005-06-03  1:41 UTC (permalink / raw)


"Robert A Duff" <bobduff@shell01.TheWorld.com> wrote in message 
news:wccoeav8tin.fsf@shell01.TheWorld.com...
[snip]
> When I say "pointer", I don't mean it has to be implemented as a single
> machine address.  It could be an offset from some known base address, an
> index into an array, or (as you say) a fat pointer -- among other
> things.
>
> The same is true of pointers in C and C++ -- an implementation is free
> to implement pointers as something other than a machine address.  In
> fact, if a C compiler wishes to check array bounds, it pretty much *has*
> to use fat pointers.  I know of one C compiler that did just that.  My
> point is that "pointer" is not synonymous with "single machine address",
> even in C.

While some C/C++ compilers may have checked array bounds, I'm not so sure it 
complies with a standard.  I don't have a copy of the standard available to 
check.

I do know that it is a common C idiom to describe a structure something 
like:

struct Data_Container
{
    int nbValues;
    int data[1];
}

...
numElements = 100;
struct Data_Container* dc = malloc( sizeof(Data_Container) + sizeof(int) 
*( numElements - 1));

dc->nbValues = numElements;
for( i = 0 ; i < dc->nbValues ; i++ )
{
    dc->data[ i ] = 0;
}

Which would not work if array bounds were checked.

I have heard of tools that will do array bounds checking with C, that give 
some way of describing the above example, but I don't think it is really 
part of the C/C++ standard.

I'm suprised the compiler that did check array bounds was validated... oh 
wait a minute ;-)

Steve
(The Duck)





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

* Re: memory management
  2005-06-03  1:41       ` Steve
@ 2005-06-03 10:12         ` alex goldman
  2005-06-13  4:01         ` Dave Thompson
  1 sibling, 0 replies; 23+ messages in thread
From: alex goldman @ 2005-06-03 10:12 UTC (permalink / raw)


Steve wrote:

> struct Data_Container
> {
>     int nbValues;
>     int data[1];
> }
> 
> ...
> numElements = 100;
> struct Data_Container* dc = malloc( sizeof(Data_Container) + sizeof(int)
> *( numElements - 1));
> 
> dc->nbValues = numElements;
> for( i = 0 ; i < dc->nbValues ; i++ )
> {
>     dc->data[ i ] = 0;
> }

I think the results of doing this are undefined, according to the standard.
In fact, the section on pointer arithmetic says even something like

int* p = malloc(100*sizeof(int));

p = p + 101; // more than 1 off
p = p -  50; 
             

is allowed to lead to undefined behavior. The pointer doesn't even need to
be dereferenced! So the C standard certainly doesn't forbid bounds
checking. Why C compilers don't come with this feature as an /option/ has
always puzzled me.



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

* Re: memory management
  2005-06-03  1:41       ` Steve
  2005-06-03 10:12         ` alex goldman
@ 2005-06-13  4:01         ` Dave Thompson
  1 sibling, 0 replies; 23+ messages in thread
From: Dave Thompson @ 2005-06-13  4:01 UTC (permalink / raw)


On Thu, 2 Jun 2005 18:41:07 -0700, "Steve"
<nospam_steved94@comcast.net> wrote:
<snip>
> While some C/C++ compilers may have checked array bounds, I'm not so sure it 
> complies with a standard.  I don't have a copy of the standard available to 
> check.
> 
It definitely does. Accessing out of declared bounds of an array is
undefined behavior (equivalent to erroneous in Ada) and is not
required to work in any particular or bounded way and also not
required to be diagnosed -- but diagnosis is permitted if the
implementation (implementor) wants to. But, and an important but, all
bytes of an object's storage can standardly be accessed as an array of
character. Precisely, they can all be _addressed_ with any flavor
character pointer, and can be fetched as unsigned char; signed char,
and plain char if an implementation chooses to make it signed, can at
least in theory have 'trap representations' fetching of which is
undefined. In practice this isn't done for integer types, mostly only
floating-point (NaNs etc.) and very occasionally pointers.

If you want them, C99 (9899) and C++ (14882) are available from ANSI
webstore.ansi.org in PDF for personal use for USD 18 (each) by credit
card (some people have reported trouble with non-USD cards). The ANSI
terms include an indemnification clause that some fairly respected
regulars on comp.{lang,std}.c feel is too broad; judge for yourself.
INCITS (former X3) also has their own store, or used to. Or C99 with
TC1 and Rationale is reliably reported to be published in traditional
book form by Wiley with BSI as ISBN 0470845732, also C++ as
0470846747. TC1,2 are free-beer at ANSI.

Or, the last public draft of C99 is free-beer 'next door' to WG9 at
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n869/ 
and earlier drafts and other committee documents up 1 or 2.
Although not identical to the adopted standard, the differences are
mostly minor and obscure -- one does come up every few months or so in
discussions on comp.lang.c -- and the draft is also in .txt and PS.

C90 was AFAIK published by (or under) ANSI only in the expensive
scanned form (about USD 200) and even that has disappeared now,
although there was the Schildt version if you can find it used (as I
did) and ignore the less-than-worthless annotations. There were claims
about a year ago that BSI had been convinced to re-publish C90 on the
basis that it is a specific (nonsuperseded) normative reference for
C++, even though no longer for C; I never found it there myself. ANSI
does show DIN and AS versions.

> I do know that it is a common C idiom to describe a structure something 
> like: <snip>
> Which would not work if array bounds were checked.
> 
This is called the 'struct hack', see 2.6 in the C FAQ at the usual
places and http://www.eskimo.com/~scs/C-faq/top.html .
(In fact on searching to check something I discovered it's even
indexed in C99 under 'struct hack' although that isn't in the body!)

It does work on all or at least nearly all implementations precisely
because they don't check, but it is officially undefined behavior --
explicitly (re)stated for C90 by (the response to) Defect Report 051,
see at the website above. (DR#s below 200 are C90; above C99.)

However, precisely because it is often useful, C99 adds a specific
syntax for it called 'Flexible Array Member', which is to declare the
last member (component) of a struct as an array with _no_ specified
bound, and that type can then legally be used to access suitable
actual objects of any size. This also avoids the ugly and easily
forgotten adjustment of the length computation by one; other than that
it is actually implemented the same as the 'hack'. AFAICS the
restrictions on allocating FAM-structs mean that you _could_ put in
dope to check them, but I don't know any implementation that does.

> I have heard of tools that will do array bounds checking with C, that give 
> some way of describing the above example, but I don't think it is really 
> part of the C/C++ standard.
> 
It is permitted, but not required and not expected or demanded or even
(mostly?) wanted by (C) users and hence not done. And since C uses
pointers all over the place, in particular all array accesses and 'by
reference' parameters at least formally use pointers, the cost of
checking pointers tends to occur 'everywhere' or at least more places
than needed in more disciplined languages including Ada, which further
discourages C implementors from providing it or already largely
unenthustiastic users from requesting it. 

Note that even the not-widely-enough-used 'memory debugging' or
specifically 'malloc debugging' tools often check only that accesses
are within an entire allocated object, not necessarily within an array
within that object (as a struct field or a multidim array 'row'). Of
course where the whole object is the array this doesn't matter.

- David.Thompson1 at worldnet.att.net



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

end of thread, other threads:[~2005-06-13  4:01 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-26  0:57 memory management alex goldman
2005-05-26  2:14 ` David C. Hoos, Sr.
2005-05-26 13:21   ` Steve
2005-05-26 18:40     ` alex goldman
2005-05-28  2:13       ` Steve
2005-05-28  5:19         ` Jeffrey Carter
2005-05-28 14:48           ` Steve
2005-05-26 18:47     ` Pascal Obry
2005-05-27 14:33   ` Martin Krischik
2005-05-26 12:10 ` Robert A Duff
2005-05-27 14:31   ` Martin Krischik
2005-05-28 11:44     ` Robert A Duff
2005-05-28 13:03       ` Simon Wright
2005-05-31 12:04         ` Robert A Duff
2005-06-02 15:42       ` Thomas Maier-Komor
2005-06-02 17:05         ` Robert A Duff
2005-06-03  1:41       ` Steve
2005-06-03 10:12         ` alex goldman
2005-06-13  4:01         ` Dave Thompson
  -- strict thread matches above, loose matches on Subject: below --
2005-04-19 20:30 Memory_Management Anh Vo
2005-04-19  1:39 Memory_Management Bini
2005-04-19  9:18 ` Memory_Management Duncan Sands
2005-04-20  1:06   ` Memory_Management Bini

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