Размер этих структур различен в файле, но одинаков в программной памяти.

Рассмотрим следующую структуру POD:

struct MessageWithArray {
uint32_t raw;
uint32_t myArray[10];

//MessageWithArray() : raw(0), myArray{ 10,20,30,40,50,60,70,80,90,100 } {  };
};

Запуск следующего:

#include <type_traits>
#include <iostream>
#include <fstream>
#include <string>

struct MessageWithArray {
uint32_t raw;
uint32_t myArray[10];

//MessageWithArray() : raw(0), myArray{ 10,20,30,40,50,60,70,80,90,100 } {  };
};

//https://stackoverflow.com/questions/46108877/exact-definition-of-as-bytes-function
template <class T>
char* as_bytes(T& x) {
return &reinterpret_cast<char&>(x);
// or:
// return reinterpret_cast<char*>(std::addressof(x));
}

int main() {
MessageWithArray msg = { 0, {0,1,2,3,4,5,6,7,8,9} };
std::cout << "Size of MessageWithArray struct: " << sizeof(msg) << std::endl;
std::cout << "Is a POD? " << std::is_pod<MessageWithArray>() << std::endl;
std::ofstream buffer("message.txt");
buffer.write(as_bytes(msg), sizeof(msg));
return 0;
}

Дает следующий вывод:

Размер структуры MessageWithArray: 44

Это POD? 1

Шестнадцатеричный дамп файла «message.txt» выглядит так:

00  00  00  00  00  00  00  00  01  00  00  00  02  00  00  00
03  00  00  00  04  00  00  00  05  00  00  00  06  00  00  00
07  00  00  00  08  00  00  00  09  00  00  00

Теперь, если я раскомментирую конструктор (так что MessageWithArray имеет конструктор с нулевым аргументом), MessageWithArray становится не-POD структурой. Затем я использую конструктор для инициализации. Это приводит к следующим изменениям в коде:

....
struct MessageWithArray {
.....

MessageWithArray() : raw(0), myArray{ 10,20,30,40,50,60,70,80,90,100 }{  };
};
....
int main(){
MessageWithArray msg;
....
}

Запустив этот код, я получаю:

Размер структуры MessageWithArray: 44

Это POD? 0

Шестнадцатеричный дамп файла «message.txt» выглядит так:

00  00  00  00  0D  0A  00  00  00  14  00  00  00  1E  00  00
00  28  00  00  00  32  00  00  00  3C  00  00  00  46  00  00
00  50  00  00  00  5A  00  00  00  64  00  00  00

Теперь, я не очень интересуюсь фактическими шестнадцатеричными значениями, что мне интересно почему в дампе структуры без POD есть еще один байт по сравнению с дампом структуры POD, когда sizeof () объявляет, что они имеют одинаковое количество байтов? Возможно ли, что, поскольку конструктор делает структуру не POD, что-то скрытое было добавлено в структуру? sizeof () должна быть точной проверкой во время компиляции, правильно? Возможно ли что-то избежать измерения с помощью sizeof ()?

Характеристики: Я запускаю это в пустом проекте в Visual Studio 2017 версии 15.7.5, Microsoft Visual C ++ 2017, на компьютере с Windows 10.

Процессор Intel Core i7-4600M
64-разрядная операционная система, 64-разрядный процессор

РЕДАКТИРОВАТЬЯ решил инициализировать структуру, чтобы избежать неопределенного поведения, и потому что вопрос все еще актуален при инициализации. Инициализация его значением без 10 сохраняет поведение, которое я наблюдал вначале, потому что данные в массиве никогда не содержали никаких десятков (даже если это были мусорные и случайные).

-2

Решение

Это не имеет ничего общего с ПОД.

Ваш ofstream открывается в текстовом режиме (а не в двоичном режиме). На окнах это означает, что \n превращается в \r\n,

Во втором случае оказался один 0x0A (\nбайт в структуре, которая стала 0x0D 0x0A (\r\n). Вот почему вы видите дополнительный байт.


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

8

Другие решения

Другой ответ объясняет проблему с записью двоичных данных в поток, открытый в текстовом режиме, однако этот код в корне неверен. Нет необходимости что-либо сбрасывать, можно использовать правильный способ проверить размеры этих структур и убедиться, что они равны static_assert:

struct MessageWithArray {
uint32_t raw;
uint32_t myArray[10];
};

struct NonPodMessageWithArray {
uint32_t raw;
uint32_t myArray[10];

NonPodMessageWithArray() : raw(0), myArray{ 10,20,30,40,50,60,70,80,90,100 } {}
};

static_assert(sizeof(MessageWithArray) == sizeof(NonPodMessageWithArray));

онлайн компилятор

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector