Странный эффект с sizeof - PullRequest
       10

Странный эффект с sizeof

0 голосов
/ 01 ноября 2010

Следующий код работает как задумано:

template <typename T>
inline char* Utils::PushData(char* destination, T data)
{
    memcpy(destination, &data, sizeof(data));
    destination += sizeof(T);
    return destination;
}

Однако, когда я использую это:

template <typename T>
inline char* Utils::PushData(char* destination, T data)
{
    memcpy(destination, &data, sizeof(T));
    destination += sizeof(T);
    return destination;
}

модель, которую я строю, испорчена.Почему это случилось?Конечно, sizeof(T) и sizeof(data) должны быть одинаковыми, верно?Или я неправильно понял, что sizeof на самом деле получает размер?

edit

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

inline char* Utils::PushXYZ(char* destination, float xValue, float yValue, float zValue)
{
    destination = PushData<float>(destination, xValue);
    destination = PushData<float>(destination, yValue);
    return PushData<float>(destination, zValue);
}

Ответы [ 4 ]

2 голосов
/ 05 ноября 2010

Конечно, sizeof (T) и sizeof (data) должны быть одинаковыми, верно?Или я неправильно понял, какой размер на самом деле получает размер?

Это не обязательно так.Рассмотрим это:

template<typename T> void f(T data);
int main() { f<char[1]>(0); }

Это даст sizeof(char[1]) применительно к T и sizeof(char*) применительно к data.В зависимости от вашего кода, у вас могут быть странные экземпляры вашего шаблона, которые могут иметь причины в таком случае.

2 голосов
/ 01 ноября 2010

Вы можете проверить в отладчике, если sizeof (T) == sizeof (data), как обычно.Не уверен на 100%, что произойдет, если T является ссылочным типом, но я думаю, что sizeof(U&) не будет таким же, как sizeof() передал параметр типа U &.

2 голосов
/ 01 ноября 2010

Использование memcpy в c ++ - очень плохая идея.

Знаете ли вы, что произойдет, если вы memcpy объект класса, который имеет виртуальные методы?Что произойдет, если вы будете использовать классы memcpy, такие как vector и string?Если вам повезло - дамп ядра.

Кстати, как вы использовали эту функцию?Что пошло не так?и т.д. Если возможно, опубликуйте минимальный компилируемый пример

1 голос
/ 01 ноября 2010

Это memcpy() ничего тебе не покупает.Используйте массив или вектор.

Вы продвигаете указатель destination на sizeof(data).Если вы используете массив, расстояние от одной записи до следующей составляет sizeof(data).Без разницы.

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

Если вы используете стандартный тип, такой как float при редактировании, то нет ни одной потраченной памятиспособ сделать это.

Вы не предоставили ни одного примера того, как вы тестировали, или какие результаты вы получили, даже в своем редактировании, поэтому никто не сможет помочь вам с этим.

...