Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > About regaining the memory associated with a block-specific variableand reusing it further.

Reply
Thread Tools

About regaining the memory associated with a block-specific variableand reusing it further.

 
 
Myth__Buster
Guest
Posts: n/a
 
      02-01-2011
NOTE : I am using the terms "reuse" or "reusable" with respect to
the object code generated at the compilation time.

/*
* Program to analyze whether it is meaningful to reuse the
* stack memory once the respective variable goes out of
* scope.
*/

#include<stdio.h>

int main()
{
int a; /* Let's say this has the address : A. */
printf("\n &a = %p ", &a);

{
int b; /* Let's say this has the address : B. */
printf("\n &b = %p", &b);
}

int c; /* Let's say this has the address : C. */
printf("\n &c = %p", &c);

return 0;
}

Win32 O/P:
&a = 0022FF74
&b = 0022FF70
&c = 0022FF6C

Fedora Core Linux O/P:
&a = 0xbfaec044
&b = 0xbfaec040
&c = 0xbfaec03c

Here, I think that C could be same as B since the respective memory
becomes reusable once the variable 'b' goes out of scope, But, the
behavior of this program differs from what I think as above when
tested
on platforms - Windows XP and Fedora Core Linux with GCC versions
3.4.2 (Thread model - win32) and 3.4.6 (Thread model - posix)
respectively.

This behavior looks like being closely related to the implementation
of the compiler in deciding the memory utilization for the local
variables. However, it would be interesting to know whether are
there any restrictions imposed by Standard C(C99) in doing so(reuse)
as
far as the language "C" is concerned.

Cheers.


 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-01-2011
Myth__Buster <(E-Mail Removed)> writes:

> NOTE : I am using the terms "reuse" or "reusable" with respect to
> the object code generated at the compilation time.
>
> /*
> * Program to analyze whether it is meaningful to reuse the
> * stack memory once the respective variable goes out of
> * scope.
> */
>
> #include<stdio.h>
>
> int main()
> {
> int a; /* Let's say this has the address : A. */
> printf("\n &a = %p ", &a);


Technically, you should say printf("\n &a = %p ", (void *)&a); here.

> {
> int b; /* Let's say this has the address : B. */
> printf("\n &b = %p", &b);
> }
>
> int c; /* Let's say this has the address : C. */
> printf("\n &c = %p", &c);
>
> return 0;
> }
>
> Win32 O/P:
> &a = 0022FF74
> &b = 0022FF70
> &c = 0022FF6C
>
> Fedora Core Linux O/P:
> &a = 0xbfaec044
> &b = 0xbfaec040
> &c = 0xbfaec03c
>
> Here, I think that C could be same as B since the respective memory
> becomes reusable once the variable 'b' goes out of scope, But, the
> behavior of this program differs from what I think as above when
> tested
> on platforms - Windows XP and Fedora Core Linux with GCC versions
> 3.4.2 (Thread model - win32) and 3.4.6 (Thread model - posix)
> respectively.
>
> This behavior looks like being closely related to the implementation
> of the compiler in deciding the memory utilization for the local
> variables.


Yes, it is.

> However, it would be interesting to know whether are
> there any restrictions imposed by Standard C(C99) in doing so(reuse)
> as
> far as the language "C" is concerned.


The main one is that an object has a constant address throughout its
lifetime. Combine this with the fact that addresses compare equal when
they refer to the same object and you will have most of the rules you
need.

The compiler can always break C's rules if the program can't tell the
difference. For example, a, b and c could be allocated at the same
location (or even not at all) if you did not take the address of any of
them and the usage permitted such re-use. I don't think gcc spends much
time trying to reduce the space used by local objects so you are
unlikely to see this in practise.

--
Ben.
 
Reply With Quote
 
 
 
 
Myth__Buster
Guest
Posts: n/a
 
      02-01-2011
On Feb 1, 6:15*am, Ben Bacarisse <(E-Mail Removed)> wrote:
> Myth__Buster <(E-Mail Removed)> writes:
> > NOTE : I am using the terms "reuse" or "reusable" with respect to
> > the object code generated at the compilation time.

>
> > /*
> > ** * *Program to analyze whether it is meaningful to reuse the
> > ** * *stack memory once the respective variable goes out of
> > ** * *scope.
> > **/

>
> > #include<stdio.h>

>
> > int main()
> > {
> > * *int a; */* Let's say this has the address : A. */
> > * *printf("\n &a = %p ", &a);

>
> Technically, you should say printf("\n &a = %p ", (void *)&a); here.
>
>
>
>
>
>
>
>
>
> > * *{
> > * * * * * *int b; /* Let's say this has the address : B. */
> > * * * * * *printf("\n &b = %p", &b);
> > * *}

>
> > * *int c; /* Let's say this has the address : C. */
> > * *printf("\n &c = %p", &c);

>
> > * *return 0;
> > }

>
> > Win32 O/P:
> > &a = 0022FF74
> > &b = 0022FF70
> > &c = 0022FF6C

>
> > Fedora Core Linux O/P:
> > &a = 0xbfaec044
> > &b = 0xbfaec040
> > &c = 0xbfaec03c

>
> > Here, I think that C could be same as B since the respective memory
> > becomes reusable once the variable 'b' goes out of scope, But, the
> > behavior of this program differs from what I think as above when
> > tested
> > on platforms - Windows XP and Fedora Core Linux with GCC versions
> > 3.4.2 (Thread model - win32) and 3.4.6 (Thread model - posix)
> > respectively.

>
> > This behavior looks like being closely related to the implementation
> > of the compiler in deciding the memory utilization for the local
> > variables.

>
> Yes, it is.
>
> > However, it would be interesting to know whether are
> > there any restrictions imposed by Standard C(C99) in doing so(reuse)
> > as
> > far as the language "C" is concerned.

>
> The main one is that an object has a constant address throughout its
> lifetime. *Combine this with the fact that addresses compare equal when
> they refer to the same object and you will have most of the rules you
> need.
>
> The compiler can always break C's rules if the program can't tell the
> difference. *For example, a, b and c could be allocated at the same
> location (or even not at all) if you did not take the address of any of
> them and the usage permitted such re-use. *I don't think gcc spends much
> time trying to reduce the space used by local objects so you are
> unlikely to see this in practise.
>
> --
> Ben.


Okay. Actually, my idea was to optimize the stack usage by the local
arrays
of reasonable sizes specific to blocks.

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-01-2011
Myth__Buster <(E-Mail Removed)> writes:
<snip>
> Okay. Actually, my idea was to optimize the stack usage by the local
> arrays
> of reasonable sizes specific to blocks.


In that case, if the arrays are not variably modified, you could put
those that can be reused into a union. If they are of the same element
type, you could even dispense with the union, but it helps to keep the
naming clear.

Your example with single ints would then be:

int a;
/* ... */
union { int b, c; } b_or_c;
{
/* use b_or_c.b here */
}
/* use b_or_c.c here */

If the arrays are variably modified and of different types, then I am
not sure what the best strategy might be. I think it would depend on
exactly what you are doing.

--
Ben.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      02-01-2011
Myth__Buster <(E-Mail Removed)> writes:
> NOTE : I am using the terms "reuse" or "reusable" with respect to
> the object code generated at the compilation time.
>
> /*
> * Program to analyze whether it is meaningful to reuse the
> * stack memory once the respective variable goes out of
> * scope.
> */
>
> #include<stdio.h>
>
> int main()
> {
> int a; /* Let's say this has the address : A. */
> printf("\n &a = %p ", &a);
>
> {
> int b; /* Let's say this has the address : B. */
> printf("\n &b = %p", &b);
> }
>
> int c; /* Let's say this has the address : C. */
> printf("\n &c = %p", &c);
>
> return 0;
> }


The lifetimes of both a and c cover the entire block that encloses
their declarations. The lifetime of b covers the inner block in
which it's declared. Thus b and c have overlapping lifetimes,
and cannot (in the abstract machine) share the same address.

You might think that the lifetime of c starts at its declaration,
but C99 6.2.4p5 says otherwise; it exists starting on entry to
the block, but its value is indeterminate until its declaration
is reached. It's possible to contrive a program that stores the
address of c in an int* variable, then uses goto to branch to
a point before its declaration; that code can access the object
"before" its declaration.

If you hadn't displayed the addresses of the objects, the compiler
could store them in the same location, as long as the program's
visible behavior isn't affected by the optimization.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Myth__Buster
Guest
Posts: n/a
 
      02-01-2011
On Feb 1, 8:17*am, Ben Bacarisse <(E-Mail Removed)> wrote:
> Myth__Buster <(E-Mail Removed)> writes:
>
> <snip>
>
> > Okay. Actually, my idea was to optimize the stack usage by the local
> > arrays
> > of reasonable sizes specific to blocks.

>
> In that case, if the arrays are not variably modified, you could put
> those that can be reused into a union. *If they are of the same element
> type, you could even dispense with the union, but it helps to keep the
> naming clear.
>
> Your example with single ints would then be:
>
> * int a;
> * /* ... */
> * union { int b, c; } b_or_c;
> * {
> * * * /* use b_or_c.b here */
> * }
> * /* use b_or_c.c here */
>
> If the arrays are variably modified and of different types, then I am
> not sure what the best strategy might be. *I think it would depend on
> exactly what you are doing.
>
> --
> Ben.


Yes. Nice to see the other possibility. But, I just tried my hands on
the approach where the compiler does the job for you instead as I
said
earlier. And I agree that if it were VLAs it might need some more
tweaking
before one can zero in on the suitable strategy herein.
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      02-01-2011
On 2011-02-01, Myth__Buster <(E-Mail Removed)> wrote:
> However, it would be interesting to know whether are
> there any restrictions imposed by Standard C(C99) in doing so(reuse)
> as
> far as the language "C" is concerned.


None, it's all undefined behavior.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
Seebs
Guest
Posts: n/a
 
      02-01-2011
On 2011-02-01, Myth__Buster <(E-Mail Removed)> wrote:
> Okay. Actually, my idea was to optimize the stack usage by the local
> arrays
> of reasonable sizes specific to blocks.


This is unlikely to yield a good return on your time.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / (E-Mail Removed)
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
 
Reply With Quote
 
Myth__Buster
Guest
Posts: n/a
 
      02-01-2011
On Feb 1, 8:30*am, Keith Thompson <(E-Mail Removed)> wrote:
> Myth__Buster <(E-Mail Removed)> writes:
> > NOTE : I am using the terms "reuse" or "reusable" with respect to
> > the object code generated at the compilation time.

>
> > /*
> > ** * *Program to analyze whether it is meaningful to reuse the
> > ** * *stack memory once the respective variable goes out of
> > ** * *scope.
> > **/

>
> > #include<stdio.h>

>
> > int main()
> > {
> > * *int a; */* Let's say this has the address : A. */
> > * *printf("\n &a = %p ", &a);

>
> > * *{
> > * * * * * *int b; /* Let's say this has the address : B. */
> > * * * * * *printf("\n &b = %p", &b);
> > * *}

>
> > * *int c; /* Let's say this has the address : C. */
> > * *printf("\n &c = %p", &c);

>
> > * *return 0;
> > }

>
> The lifetimes of both a and c cover the entire block that encloses
> their declarations. *The lifetime of b covers the inner block in
> which it's declared. *Thus b and c have overlapping lifetimes,
> and cannot (in the abstract machine) share the same address.


If this turns out to be the case, I could see that some stack space
being eaten up by the variables yet unused in the outermost block.
Well, this could be an inefficient object code generation as well
right? The inefficiency here I am referring is in terms of memory
space consumption.

Having said that, I could see no other sort of manipulations to avoid
this compile-time inefficiency in case the control doesn't reach the
yet
unused variables as mentioned above. If there are, then I would be
eager to know them.

>
> You might think that the lifetime of c starts at its declaration,
> but C99 6.2.4p5 says otherwise; it exists starting on entry to
> the block, but its value is indeterminate until its declaration
> is reached. *It's possible to contrive a program that stores the
> address of c in an int* variable, then uses goto to branch to
> a point before its declaration; that code can access the object
> "before" its declaration.
>


Yes, I agree on this - bad coding practice but interesting
possibility
as well..

> If you hadn't displayed the addresses of the objects, the compiler
> could store them in the same location, as long as the program's
> visible behavior isn't affected by the optimization.
>


Yes, that seems feasible. I tried with the same win32 GCC and printed
the addresses of b and C through GDB. Unless I try to print their
addresses,
they are having the same addresses - tried assigning a value to it,
etc.
So, that's a good finding for me.. Thanks.

> --
> Keith Thompson (The_Other_Keith) (E-Mail Removed) *<http://www.ghoti.net/~kst>
> Nokia
> "We must do something. *This is something. *Therefore, we must do this."
> * * -- Antony Jay and Jonathan Lynn, "Yes Minister"


 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      02-01-2011
Ben Bacarisse <(E-Mail Removed)> writes:
> Myth__Buster <(E-Mail Removed)> writes:
> <snip>
>> Okay. Actually, my idea was to optimize the stack usage by the local
>> arrays
>> of reasonable sizes specific to blocks.

>
> In that case, if the arrays are not variably modified, you could put
> those that can be reused into a union. If they are of the same element
> type, you could even dispense with the union, but it helps to keep the
> naming clear.
>
> Your example with single ints would then be:
>
> int a;
> /* ... */
> union { int b, c; } b_or_c;
> {
> /* use b_or_c.b here */
> }
> /* use b_or_c.c here */
>
> If the arrays are variably modified and of different types, then I am
> not sure what the best strategy might be. I think it would depend on
> exactly what you are doing.


Hmm. That strikes me as excessive micro-optimization, especially
since (in this case) all it saves you is the storage for a single
int. And b_or_c might as well be an int rather than a union.

Crank up the optimization level on your compiler, *don't* take
the address of the variables in your code, and take a look at the
generated assembly to see if it manages to reuse the same memory
(or, perhaps more likely, just keep the values in registers).

Or, if you haven't demonstrated a real need to save storage,
consider not worrying about it.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
regaining partition news.ntlworld.com Computer Support 5 04-02-2008 01:37 AM
Reusing HttpWebRequest.GetRequestStream Dan ASP .Net 4 06-01-2007 07:29 AM
Reusing DataSet/DataTable anon ASP .Net 1 04-01-2004 04:53 PM
Session Variables and reclaiming associated memory. Mario ASP General 1 02-18-2004 01:08 PM
reusing a bit of code? Rob Meade ASP .Net 4 01-30-2004 02:47 PM



Advertisments