「サイズはコンパイル時ではなく実行時に決定される」という意味で動的サイズの構造体を使用する場合、構造体の最後のメンバーとしてfloat value[]
のような不特定のサイズの配列を使用できます。ただし、構造体に適切なサイズのメモリを手動で割り当てる必要があります。これはCの場合であり、C++の場合もそうです。残念ながら、new
はタイプを使用してランタイム値ではなく型を使用するため、オペレータnew
を使用する場合は手動でサイズを定義するのはややこしいことです。だからおそらくmalloc
とfree
を使用しますが、C++ではどこかに間違えて見えます。
より簡単な解決策は、std::vector
を使用し、構造体メモリのダンプを書き込むのではなく、ベクターの内容を書き込むことです。
とにかく、あなたが従うアプローチごとに、配列の要素数もファイルに書き込む必要があります。さもなければ、少なくとも同じ構造体を同じファイルに順番に書き込むと、ファイルに格納されている(動的な)配列の要素の数が失われる可能性があります。もちろん、読み込みプロセスではこの数値を考慮に入れて、それに応じてstructs
を作成/変更する必要があります。
(1)ベクトルアプローチと(2)可変サイズの構造を持つ構造を示す次のコードを参照してください。それが何とか役立つことを願っています。
struct GenerationBase_UsingVector
{
std::vector<float> value;
void write(std::ofstream &w) const {
size_t num_elems = value.size();
w.write((const char*)&num_elems, sizeof(num_elems));
w.write((const char*)value.data(), num_elems*sizeof(float));
}
void read(std::ifstream &r) {
size_t num_elems;
r.read((char *)&num_elems, sizeof(num_elems));
float f;
while (num_elems--) {
r.read((char *)&f, sizeof(f));
value.push_back(f);
}
}
};
struct GenerationBase_PlainArray
{
size_t num_elems;
float value[];
static GenerationBase_PlainArray* create(size_t num_elems)
{
GenerationBase_PlainArray* result = (GenerationBase_PlainArray*)malloc(sizeof(GenerationBase_PlainArray) + num_elems*sizeof(float));
result->num_elems = num_elems;
return result;
}
static struct GenerationBase_PlainArray* newFromStream(std::ifstream &r) {
size_t num_elems;
r.read((char *)&num_elems, sizeof(num_elems));
GenerationBase_PlainArray* result = GenerationBase_PlainArray::create(num_elems);
r.read((char *)result->value, num_elems*sizeof(float));
return result;
}
void write(std::ofstream &w) const {
w.write((const char*)&num_elems, sizeof(num_elems));
w.write((const char*)value, num_elems*sizeof(float));
}
};
int main() {
GenerationBase_UsingVector gb_vector_forwrite;
gb_vector_forwrite.value.push_back(1.0);
gb_vector_forwrite.value.push_back(2.0);
gb_vector_forwrite.value.push_back(3.0);
gb_vector_forwrite.value.push_back(4.0);
gb_vector_forwrite.value.push_back(5.0);
gb_vector_forwrite.value.push_back(6.0);
std::ofstream write("test.bin", std::ios::binary);
gb_vector_forwrite.write(write);
write.close();
GenerationBase_UsingVector gb_vector_forread;
std::ifstream read("test.bin", std::ios::binary);
gb_vector_forread.read(read);
read.close();
for (auto f : gb_vector_forread.value) {
cout << f << endl;
}
GenerationBase_PlainArray* gb_array_forwrite = GenerationBase_PlainArray::create(6);
gb_array_forwrite->value[0] = 1.0;
gb_array_forwrite->value[1] = 2.0;
gb_array_forwrite->value[2] = 3.0;
gb_array_forwrite->value[3] = 4.0;
gb_array_forwrite->value[4] = 5.0;
gb_array_forwrite->value[5] = 6.0;
std::ofstream write2("test2.bin", std::ios::binary);
gb_array_forwrite->write(write2);
write2.close();
free(gb_array_forwrite);
std::ifstream read2("test2.bin", std::ios::binary);
GenerationBase_PlainArray *gb_array_forread = GenerationBase_PlainArray::newFromStream(read2);
read2.close();
for (int i=0; i<gb_array_forread->num_elems; i++) {
cout << gb_array_forread->value[i] << endl;
}
free(gb_array_forread);
}
'ド/ Serialiazation'.httpの使用を検討してください://www.boost.org/doc/libs/1_36_0/libs/serialization/doc/index.html – Raindrop7
のsizeof(T)は、コンパイル時のものです - あなたの配列が動的な場合はオプションではありません。 – WindyFields
'ベクトル 'は単純なデータ配列より複雑です。あなたはそれのアドレスを取ることはできません。 – AndyG