storage allocation?

T

Timothee Groleau

Hi,

Is it defined in C++ that 2 arrays of the same type defined one after the
other are contiguous in memory?

like saying:

int a1[10];
int a2[10];

implies (a1 + 10 == a2)?

Thinking in C++ seems to imply so but I'm not finding it to be true with GCC
3.3.6 .

For example, check the exercise 18 of chapter 3 of TIC++ second edition. in
my case with GCC 3.3.6, I get this:

================
#include <iostream>
using namespace std;

int main()
{
int a1[10];
int a2[10];

cout << a1 << endl;
cout << a2 << endl;
cout << (a2 - a1) << endl;
}
================
output:
0xbfb9c0f0
0xbfb9c0c0
-12
================

What gives?

Thanks,
Tim.
 
R

Rolf Magnus

Timothee said:
Hi,

Is it defined in C++ that 2 arrays of the same type defined one after the
other are contiguous in memory?

No, unless they are themselves both elements of an array.
like saying:

int a1[10];
int a2[10];

implies (a1 + 10 == a2)?
No.

Thinking in C++ seems to imply so but I'm not finding it to be true with
GCC 3.3.6 .

For example, check the exercise 18 of chapter 3 of TIC++ second edition.
in my case with GCC 3.3.6, I get this:

================
#include <iostream>
using namespace std;

int main()
{
int a1[10];
int a2[10];

cout << a1 << endl;
cout << a2 << endl;
cout << (a2 - a1) << endl;
}
================
output:
0xbfb9c0f0
0xbfb9c0c0
-12
================

What gives?

So the book says that the last line must be 10? I hope not.
 
D

dan2online

Timothee said:
Is it defined in C++ that 2 arrays of the same type defined one after the
other are contiguous in memory?

like saying:

int a1[10];
int a2[10];

implies (a1 + 10 == a2)?

No, the result will depend on the context.
In one block:
{
int a1[10];
int a2[10];
}
a1, a2 will be allocated in stack, and meet memory alignment
requirement.
the stack frame will depend on the compiler and hardware platform.

But for class or struct
class A
{
public:
int a1[10];
int a2[10];
}

A obj; //the memory of object will be allocated from heap.

ADDRESS( obj.a1) + 0x28 = ADDRESS( obj.a2)

int *p_a1 = obj.a1;
int *p_a2 = obj.a2;

*p_a1 + 10 == *p_a2 ; // here it is true, not obj.a1+10 == obj.a2.
Thinking in C++ seems to imply so but I'm not finding it to be true with GCC
3.3.6 .

For example, check the exercise 18 of chapter 3 of TIC++ second edition. in
my case with GCC 3.3.6, I get this:

================
#include <iostream>
using namespace std;

int main()
{
int a1[10];
int a2[10];

cout << a1 << endl;
cout << a2 << endl;
cout << (a2 - a1) << endl;
}
================
output:
0xbfb9c0f0
0xbfb9c0c0
-12
================

What gives?

see the above explain.
 
D

dan2online

It does depends on your compiler,i have got this in vc6.0:

VC seems to allocate a1 and a2 array from heap, and only the pointers
are stored in the stack.

But gcc sometimes allocate memory like this, but if the memory is
small, it also allocate memory from stack directly that is a fast way.
 
J

Jakob Bieling

dan2online said:
(e-mail address removed) wrote:

VC seems to allocate a1 and a2 array from heap, and only the pointers
are stored in the stack.

How did you come to this conclusion??
 
J

Jakob Bieling

dan2online said:
Timothee said:
Is it defined in C++ that 2 arrays of the same type defined one
after the other are contiguous in memory?

like saying:

int a1[10];
int a2[10];

implies (a1 + 10 == a2)?

No, the result will depend on the context.
In one block:
{
int a1[10];
int a2[10];
}
a1, a2 will be allocated in stack, and meet memory alignment
requirement.
the stack frame will depend on the compiler and hardware platform.

As far as I know, the above might be allocated on the heap as well.
The point is, that it is automatic storage, meaning that the compiler
must make sure it is automatically destroyed when leaving the scope.

I do not know for sure and cannot be bothered to look it up now, but
I cannot remember the Standard saying anything at all when something is
allocated on the heap and when on the stack. Actually, there might not
even be a stack or a heap, depending on the platform.
But for class or struct
class A
{
public:
int a1[10];
int a2[10];
}

A obj; //the memory of object will be allocated from heap.

Uh, no. Where the stuff will be allocated, is unspecified. My
compiler will allocate the above on the stack.
ADDRESS( obj.a1) + 0x28 = ADDRESS( obj.a2)

You assume a lot of things here. Do not. The above might be false
for several reasons. One is padding (see below), another is that an
'int' might be 8 bytes.
int *p_a1 = obj.a1;
int *p_a2 = obj.a2;

*p_a1 + 10 == *p_a2 ; // here it is true, not obj.a1+10 == obj.a2.

No it is not. The compiler may insert padding byte(s) between 'a1'
and 'a2'.

hth
 
T

Timothee Groleau

Hi,

Thanks to all who replied, I appreciate it.
So the book says that the last line must be 10? I hope not.

Well, the book doesn't say that explicitly but this particular exercise is
formulated as follow:
====
Create a program that defines two int arrays, one right after the other.
Index off the end of the first array into the second, and make an
assignment. Print out the second array to see the changes cause by this.
Now try defining a char variable between the first array definition and the
second, and repeat the experiment. You may want to create an array printing
function to simplify your coding.
====

So as I tried this exercise, when I assigned "a1[11] = someInt;" and didn't
see any change in a2, I wondered what happened. By checking the addresses,
I discovered that gcc actually allocated a2 before a1 and so I got confused
on whether this exercise was not appropriate or whether gcc was
misbehaving, hence my question.

This exercise is taken from Thinking in C++, volume 1, version 2, chapter 3,
exercise 18; you can get the book (for free) here:
http://mindview.net/Books/TICPP/ThinkingInCPP2e.html

Tim.
 
D

dan2online

Jakob said:
dan2online said:
Timothee said:
Is it defined in C++ that 2 arrays of the same type defined one
after the other are contiguous in memory?

like saying:

int a1[10];
int a2[10];

implies (a1 + 10 == a2)?

No, the result will depend on the context.
In one block:
{
int a1[10];
int a2[10];
}
a1, a2 will be allocated in stack, and meet memory alignment
requirement.
the stack frame will depend on the compiler and hardware platform.

As far as I know, the above might be allocated on the heap as well.

As I mentioned, it depends on compilers you use. The original post
shows that a1 and a2 are allocated on the stack. You can double check
it using a debugger tool, like gdb.
The point is, that it is automatic storage, meaning that the compiler
must make sure it is automatically destroyed when leaving the scope.

It is correct whatever a1 and a2 are allocated either on the stack or
from the heap.
I do not know for sure and cannot be bothered to look it up now, but
I cannot remember the Standard saying anything at all when something is
allocated on the heap and when on the stack. Actually, there might not
even be a stack or a heap, depending on the platform.
Yes.
But for class or struct
class A
{
public:
int a1[10];
int a2[10];
}

A obj; //the memory of object will be allocated from heap.

Uh, no. Where the stuff will be allocated, is unspecified. My
compiler will allocate the above on the stack.

What is your compiler ? Could you show the stack frame?
Normally The memory stored the pointer tothe object will allocated on
the stack, not the object itself. I cannot make sure what the compiler
will do with optimization.
You assume a lot of things here. Do not. The above might be false
for several reasons. One is padding (see below), another is that an
'int' might be 8 bytes.


No it is not. The compiler may insert padding byte(s) between 'a1'
and 'a2'.

Your are right. I mententioned the memory alignment before.
 
J

Jakob Bieling

dan2online said:
Jakob Bieling wrote:
class A
{
public:
int a1[10];
int a2[10];
}

A obj; //the memory of object will be allocated from heap.
Uh, no. Where the stuff will be allocated, is unspecified. My
compiler will allocate the above on the stack.
What is your compiler ? Could you show the stack frame?

VC++ 8. No need for a full stack frame, tho. I can inspect the
output and see that the stack pointer is increased by 88 bytes, which
corresponds to those ints plus some padding.
Normally The memory stored the pointer tothe object will allocated on
the stack, not the object itself. I cannot make sure what the compiler
will do with optimization.

'Normally' is very subjective :) I honestly do not know many
compilers, but the ones I do know never allocate automatic objects on
the heap, but always on the stack.

regards
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,197
Messages
2,571,038
Members
47,633
Latest member
BriannaLyk

Latest Threads

Top