Адрес ссылочной переменной в c ++ - PullRequest
1 голос
/ 02 февраля 2012

У меня есть следующий код C ++

#include <iostream>

using namespace std;

 int a=100;
 int  &b = a;

int main ( int argc, char ** argv)
{

    cout << " a  "<<a<<"  b"<<b<<endl;
    b = 200;
    cout <<"a "<<a<<endl;
}

Я хотел бы видеть адрес a и b в таблице символов объектного файла?

#gcc -g -o ref ref.cpp -lstdc++

Есть такие инструменты, как objdump, readelf. но я не знаком с этими инструментами. Пожалуйста, предоставьте предложенный способ найти адрес a и b в объектном файле [т.е. в таблице символов]

ПРИМЕЧАНИЕ: я редактировал, чтобы переместить переменные из локальных в глобальные.

Ответы [ 5 ]

4 голосов
/ 02 февраля 2012

Адрес переменной Reference такой же, как адрес объекта, на который она ссылается.
т.е.:

&b == &a

И это хорошо определено стандартом и всегда будет верным.
Чего пытаетесь достичь?

1 голос
/ 02 февраля 2012
  cout << " &a  " << &a <<"  &b "<< &b <<endl;

Это покажет адрес обоих и подтвердит, что они находятся на том же адресе.

0 голосов
/ 24 мая 2012

Вы можете использовать инструмент «nm» в конечном исполняемом файле. Как это:

$ nm -C привет 080490ba A __bss_start 080490ba A _edata 080490bc A _end 08048083 T _start 08048080 т access.the.bsd.kernel 080490ac d hbytes 080490ac d hello $

Первый столбец вывода - это адрес символа, после которого идет его тип, а после него - его имя.

0 голосов
/ 02 февраля 2012

Единственный способ увидеть адрес - это использовать такие инструменты, как objdump, но вы никогда не увидите адрес локальных переменных. Они не существуют во время компиляции, размещаются в стеке во время выполнения. Единственное, что вы увидите в exe, это asm / машинный код, который выполняет push или sub sp, что является выделением.

Если вы измените свою программу на:

#include <iostream>

using namespace std;

int main ( int argc, char ** argv)
{
    static int a=100;
    static int  &b = a;
    cout << " a  "<<a<<"  b"<<b<<endl;
    b = 200;
    cout <<"a "<<a<<endl;
}

затем после компиляции сделайте:

objdump -t ref | grep data

и вы увидите:

080488a8 l    d  .rodata        00000000              .rodata
08049a94 l    d  .data          00000000              .data
080488bc l     O .rodata        00000004              _ZZ4mainE6b
08049a9c l     O .data          00000004              _ZZ4mainE6a
08049a94  w      .data          00000000              data_start
080488a8 g     O .rodata        00000004              _fp_hw
080488ac g     O .rodata        00000004              _IO_stdin_used
08049a94 g       .data          00000000              __data_start
08049a98 g     O .data          00000000              .hidden __dso_handle
08049aa0 g       *ABS*          00000000              _edata

Переменные, которые вы ищете: _ZZ4mainE6a _ZZ4mainE6b (это их искаженные имена).

РЕДАКТИРОВАТЬ: для текущей версии вашего примера кода, с глобальными символами a & b, a будет .text и b .rodata, так что теперь вам нужно будет использовать «текст» в фильтре grep, чтобы увидеть a.

0 голосов
/ 02 февраля 2012

Это локальные переменные, которые выделяются в стеке.Память и, следовательно, адрес получаются при запуске программы.

Вы не получите адрес из объектного файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...