0

I created a sample C++ program on a 64 Bit linux machine running on VMware Player over host machine as windows. The below is a class code.

        class operatorOverloadingTest{
            private:
                    int age;
                    char *name;
            public:
                    operatorOverloadingTest(int age){
                            this->age = age;
                            name = new char[10];
                            strncpy(name,"Indra",strlen("Indra"));
                    }   

                    void displayDetails(){
                            cout<<"My Name :"<<name<<endl;
                            cout <<"My age: "<<age<<endl;
                    }   
                    friend ostream & operator<<(ostream &out, const operatorOverloadingTest &myObj);
                    ~operatorOverloadingTest(){
                            delete name;
                            cout<<" \nDestructor getting called"<<endl;
                    }
    };

In my Main function, created object of class:
1. By using new operator.
2. Stack Object.

int main(){
    operatorOverloadingTest *oOT = new operatorOverloadingTest(10);
    operatorOverloadingTest oOT1(30);

I understand that, on 64-Bit machine, memory address are represented in 8 Bytes.

When I run the program using GDB, i see the below address:

p oOT
$1 = (operatorOverloadingTest *) 0x613c20
p &oOT
$2 = (operatorOverloadingTest **) 0x7fffffffe228
 &(oOT1.age)
$7 = (int *) 0x7fffffffe210
(gdb) p &(oOT->age)
$8 = (int *) 0x613c20

My question is, why does object allocated in heap shows a 32 bit address representation and the object on stack (oOT1) shows a 64 bit address representation though my operating System is 64 Bit? (Checked using uname -a).

Indra Chatterjee
  • 101
  • 1
  • 2
  • 10
  • 2
    because 0x613c20 = 0x0000000000613c20 - it truncates leading zeros – Anty Jan 23 '17 at 02:00
  • Apparently, the compiler or runtime just happened to locate heap memory in the lower 4GB of the 64-bit address space. – Igor Tandetnik Jan 23 '17 at 02:03
  • 1
    @Anty: And the reason it does that, is presumably because it's much easier to see that `0x02000000` is not `0x20000000` than it is to see that `0x0000000002000000` is not `0x0000000020000000`. – Ben Voigt Jan 23 '17 at 02:11
  • @IgorTandetnik: Yes, non PIE x86-64 executables have their static code/data mapped in the low 2GiB of virtual address space, so static addresses are usable as 32-bit absolute immediates / displacements, whether zero or sign-extended to 64-bit. This allows addressing modes like `[array + rdi*4]` for example. See [32-bit absolute addresses no longer allowed in x86-64 Linux?](https://stackoverflow.com/q/43367427) re: PIE executables changing that, and various MacOS Q&As (it always maps outside the low 4GiB, perhaps to help detect pointer truncation.) – Peter Cordes Nov 28 '21 at 03:10

1 Answers1

2

My question is, why does object allocated in heap shows a 32 bit address representation and the object on stack (oOT1) shows a 64 bit address representation

When you look at 0x1234, you know that the entity has at least 16 bits, but you can't tell whether it's 16-bit, a 32-bit, or a 64-bit entity, because GDB will not print leading zeros.

If you want to know how big some program entity is, try:

(gdb) print sizeof(oOT)
(gdb) print sizeof(&ooT)
Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • GDB does not print the leading zero's. Is there any command to check the memory map of my binary when it is loaded in RAM. This way i could check the heap segment starting and ending address and confirm that they have leading zero's. sizeof() shows the memory required by the object , i wanted to know the memory representation in the system used to address the object – Indra Chatterjee Jan 24 '17 at 16:47
  • 1
    @IndraChatterjee You are probably looking for `(gdb) info proc map` – Employed Russian Jan 24 '17 at 17:13