Дампинг переменных в C ++ - PullRequest
       11

Дампинг переменных в C ++

5 голосов
/ 11 апреля 2009

Возможно ли сделать «дамп» для сложных структур или даже массивов в C ++, чтобы визуально иметь возможность проверить, что у них внутри?

Я думаю о чем-то похожем на print_r () или var_dump () в PHP.

Ура, -Fin

Ответы [ 7 ]

8 голосов
/ 11 апреля 2009

Короткий ответ: нет, если вы сами не напишите такую ​​процедуру вручную.

Это часто неплохая идея, но у нее обычно возникают проблемы с синхронизацией с классом, если вы часто добавляете / меняете членов. Это неизбежно, потому что C ++ не обладает какой-либо формой самоанализа в struct s.

Если вы решите пойти по этому пути, лучше всего написать перегрузку для std::ostream& operator<<(std::ostream& os, MyClass const&), которая позволит вашему классу печататься в любом выходном потоке IOStreams.

4 голосов
/ 11 апреля 2009

Обычно отладчики достаточно умны, чтобы делать это.

В GDB вы можете использовать:

print structure

и в NTSD вы можете сделать супер-круто:

dt -r structure

Если вы просто используете это для целей отладки, я настоятельно рекомендую научиться использовать отладчики. Даже если вы хотите что-то зарегистрировать (например, напечатать миллион раз), вы можете установить макрос точки останова.

В NTSD:

bp yourdll!yourobject::yourfunction "dt -r structure;g"

И я уверен, что есть способ сделать это и в GDB

3 голосов
/ 11 апреля 2009

Если вы добавляете отражение в C ++ (используя стороннюю библиотеку или расширения поставщика), вы можете написать подпрограмму для использования этих данных отражения для выгрузки произвольных структур. Например, у меня есть некоторый код, который использует библиотеку CERN Reflex для перебора членов класса или структуры и вывода их в YAML .

3 голосов
/ 11 апреля 2009

В дополнение к другим ответам, в зависимости от того, для чего вы этого хотите, и от того, заботитесь ли вы о переносимости, вы можете посмотреть на получение необходимой информации из отладочной информации, которую генерирует ваш компилятор. Вы можете проанализировать файл формата COFF / ELF / независимо от формата из сборки, и это даст вам информацию, необходимую для определения имен и типов переменных в вашем объекте.

1 голос
/ 11 апреля 2009

Обычно не возможно в C ++, так как требует использования отражения, которого нет в C ++. Конечно, вы можете написать свою собственную функцию для выгрузки определенных структур данных.

0 голосов
/ 16 октября 2015

Почему вы не используете бинарные файлы? У fstream есть двоичный режим, и вы можете вывести любой тип, кроме списков struct,class,namespace или STL (например, вектор, очередь). Хотите дамп структуры, класса, пространства имен (или список STL) в двоичный файл? Сделайте функцию и выведите каждую переменную в файл! Конец! Это было бы не так сложно ... но нужна дополнительная помощь? см. этот фрагмент кода!

#include <iostream>
#include <fstream>//ofstream,ifstream
using namespace std;
ifstream myBdumpin ("data.bin"/*filename*/, ios::in);//ifstream = input
ofstream myBdumpout ("data.bin"/*filename*/, ios::out);//ofstream = output
int main()
{
    char a[8]="Binary!"
    myBdumpout << a;
    char b[8];
    myBdumpin >> b;
    if(a == b)cout << "It worked!" << endl;
    else cout << "It failed..." << endl;
    return 0;
}

Это должно работать ...

0 голосов
/ 11 апреля 2009

Действительно, в среде, где у вас есть gdb, и вы компилируете свои источники с включенными символами отладки (например, -ggdb), вы можете иметь свой отладчик (например, gdb из командной строки или ddd, когда вам нужно что-то графически).

Рассмотрим этот кусок кода:

#include <string>
#include <vector>

struct test
{
    int a;
    float b;
    std::string c;
};

int main()
{
    std::vector<int> v;

    test t;
    t.a=1;
    t.b=2.0;
    t.c="hello there";


    return 0;
}

При вежливом обращении к gdb он может дать мне следующий вывод:

(gdb) break 20
Breakpoint 1 at 0x8048622: file bla.cpp, line 20.
(gdb) run
Starting program: /home/edb/a.out 

Breakpoint 1, main () at bla.cpp:21
21      return 0;
(gdb) print t
$1 = {a = 1, b = 2, c = {static npos = 4294967295, 
    _M_dataplus = {> = {> = {}, }, _M_p = 0x96b6014 "hello there"}}}
(gdb) ping v
Undefined command: "ping".  Try "help".
(gdb) print v
$2 = { >> = {
    _M_impl = {> = {> = {}, }, _M_start = 0x0, _M_finish = 0x0, 
      _M_end_of_storage = 0x0}}, }

Редактировать: обратите внимание, что эти данные доступны из контекста отладчика, для генерации этих дампов во время выполнения вам нужно предусмотреть свою собственную функцию дампа / форматирования, обычно выполняемую с помощью перегрузки оператора << в C ++. </p>

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