Как получить размер объекта по ссылке? - PullRequest
4 голосов
/ 13 августа 2010

Предположим, у меня есть класс

class Foo {

:
:

}

У меня есть другая функция

void getf( Foo &f) {

:
:

std::cout<<sizeof f<<std::endl;
}

После того, как я обработаю данные и назначу большое количество данных для f (вектор входит в члены Foo), мне нужен размер объекта f

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

Я сделал что-то не так? Как это сделать?

Спасибо!

Ответы [ 8 ]

8 голосов
/ 13 августа 2010

sizeof возвращает размер типа. Часто, как в случае Vector, размер типа не обязательно включает совокупный размер всего, на что может указывать тип. Например, введите:

class Foo {
   char* chars
}

... будет отображать одинаковый размер результатов, независимо от того, указывает chars на один байт или на строку 40 КБ.

5 голосов
/ 13 августа 2010

Согласно этой IBM-ссылке , sizeof, примененная к ссылке, возвращает размер ссылочного объекта:

Результатом является размер ссылочного объекта.

Итак, я считаю, что проблема не в том, что sizeof возвращает размер самой ссылки, а в том, что Foo содержит указатели на другие типы.

Также сохраняйте вИмейте в виду, что sizeof не скажет вам размер данных внутри vector (или любого другого контейнера, который использует кучу).Рассмотрим следующий пример:

struct Foo {
    std::vector<int> v;
}

int main(int argc, char **argv) {
    Foo foo;
    std::cout << sizeof(foo) << std::endl;
    foo.v.push_back(1);
    std::cout << sizeof(foo) << std::endl;
}

Output:
24
24
4 голосов
/ 13 августа 2010

После того, как я обработаю данные и назначу большое количество данных для f (вектор, включенный в члены Foo), мне нужен размер объекта f

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

Если вам нужна какая-то мера общего количества байтов, связанных с объектом во время выполнения, то вы не можете просто использовать простой sizeof. Вы должны были бы сложить все части. Например: sizeof(f) + f.vector_member.size() * sizeof(whaterver_type_that_vector_contains).

1 голос
/ 13 августа 2010

sizeof в этом случае возвращает размер вашего класса.Вы говорите, что присвоили данные Foo, но не определили Foo.Я подозреваю, что это выглядит примерно так:

class Foo
{
public:
  string my_str;
  int* my_ints;
};

А затем вы делаете что-то вроде этого:

Foo f;
f.my_str = "Hello, Foo.";
f.my_ints = new int[1000];

... и ожидаете, что sizeof(f) будет теперь размером Fooплюс размер строки плюс размер массива int.Но это не так.Foo никогда не изменяется в размере, потому что у него нет "массива" или массива типа int.Скорее, он имеет объект string (который, в свою очередь, вероятно, имеет указатель на массив символов) и указатель на int.Память, выделенная для строки и массива int, не находится в Foo, на нее указывает Foo.

0 голосов
/ 13 августа 2010

Просто дополнительная заметка:

$ 8.3.2 / 3 состояния- «Не определено, требует ли ссылка хранения (3.7).»

Поэтому не всегда следует предполагать, что ссылка занимает память. sizeof при применении к операнду-ссылке возвращает статическое время компиляции sizeof исходного реферада.

0 голосов
/ 13 августа 2010

Если у вас есть такой класс:

class Foo
{
    std::vector<int> intVec;

    // ....
};

, оператор sizeof, работающий во время компиляции, будет включать только размер элементов данных экземпляра vector.Он не даст вам общий размер элементов вектора, которые хранятся где-то в куче и на которые указывает какой-то закрытый член вектора.

Если вы действительно пытаетесь выяснить общую суммупамяти, используемой вектором, я не думаю, что есть портативный способ сделать это.Векторная реализация может выделить память, которую она не использует, поэтому, не глядя на реализацию, вы на самом деле не знаете, что она делает.

0 голосов
/ 13 августа 2010

Используя этот тестовый пример:

class Foo 
{ 
    char x [100];  
} ;

void getf( Foo &f) 
{ 
    std::cout<<"sizeof f:" << sizeof f<<std::endl; 
} 

Я получаю sizeof f:100 напечатано.Итак, ваш код верен;Вы просто неправильно это понимаете.

0 голосов
/ 13 августа 2010

Можете ли вы перечислить структуру вашего класса F. Я подозреваю, что вы получаете правильный размер, sizeof сообщит вам размер класса, который является размером всех членов класса (это основано на на выравнивание и порядок, а также ваш компилятор). Он не сообщит вам размер вектора, включая его элементы, только размер ссылки на вектор.

...