2016-10-27 23 views
0

バイナリファイルに間違って書き込みしていると思います。グレードやユニットなどの詳細を含むリストに大学のコースを追加するプログラムを作成することになっています。配列にアイテムを追加するたびに配列の容量を倍増することになっています(doubleArrayCapacity関数)C++動的配列のシリアライズ

void doubleArrayCapacity(Course*&, int&, int); 

    ... 

    int cap = 2; 
    int size = 0; 
    Course* courses = new Course[cap]; 

    fstream fin; 
    fin.open("myCollegeCourses.9.bat", ios::binary|ios::in); 
    if (fin.good()) 
    { 
    fin.read(reinterpret_cast<char*>(&size), sizeof(size)); 
    doubleArrayCapacity(courses, cap, size); 
    fin.read(reinterpret_cast<char*>(courses), cap * sizeof(Course)); 
    } 
    fin.close(); 

    ... 

    fstream fout; 
    fout.open("myCollegeCourses.9.bat", ios::binary|ios::out); 
    fout.write(reinterpret_cast<char*>(&size), sizeof(size)); 
    fout.write(reinterpret_cast<char*>(courses), cap * sizeof(Course)); 
    fout.close(); 

    ... 

    void doubleArrayCapacity(Course*& array, int& capacity, int newCapacity) 
    { 
    Course* temp = new Course[2 * capacity]; 
    for (int i = 0; i < capacity; i++) 
     temp[i] = array[i]; 
    delete [ ] array; 
    array = temp; 
    capacity = newCapacity * 2; 
    } 

私の配列に4つの項目を追加すると、プログラムは正常に動作します。 5つのオブジェクトに到達すると、エラーが発生します。ファイルが正しく読み取られず、5番目の項目がヌルまたはゼロとして読み取られます。私はバイナリファイルにデータを正しく出力していないと思います。誰かが私が間違っているのを見ることができますか?

+0

通常は、新しいエントリは、既存の容量の範囲内で使用すると、エントリを追加しないたびに合わないだけで二重の能力を、だろう。毎回サイズを2倍にすると、初期化されていないデータが効果的に配列に挿入されます。 – Meixner

+0

BTW:このデータをディスクに書き出すことは、数値が異なる表現(ビッグエンディアンとリトルエンディアン)を持つ可能性があり、データ型のアラインメントが構造体の異なるパディングにつながる異なる要件を持つ可能性があるため、 – Meixner

答えて

1

私が見ることができるように、あなたはここで2つの潜在的な問題を抱えている

  1. まず問題はシリアル化である、シリアライズのfout.write(reinterpret_cast<char*>(courses), cap * sizeof(Course));正しさはCourseオブジェクトのデータメンバの内部レイアウトやアライメントに依存します。
  2. 第2の潜在的な問題は、void doubleArrayCapacity機能の実装にあります。文temp[i] = array[i];があなたの望むことをするためには、Course代入演算子を実装する必要があります。 「コース」は複雑なデータメンバとポインタを持っていないことを確認してください

    1. レビュー「コース」
    2. のデータメンバのアライメントを:

    とにかく、私はあなたをお勧めします。

もう1つの方法は、Courseのクラスおよびデシリアライズコンストラクタにserializeメソッドを追加することです。

+0

あなたのアドバイスをありがとう。これは私のコース構造体 'struct course { char title [13]; int year; int単位; charグレード; }; ' – Norse

+0

そして、あなたは' Course'代入演算子を実装して、2番目の点について詳しく説明できますか? – Norse

+0

このような構造体については、実際には 'Course&operator =(const Course&other);' –

0

あなたはファイルにsizeを書きます。これは、そこにいくつのアイテムがあるかを示します。その後、ファイルを開き、sizeと読みます。しかし、sizeを忘れてしまった。ここsize

変更cap

fin.read(reinterpret_cast<char*>(&size), sizeof(size)); 
doubleArrayCapacity(courses, cap, size); 

//fin.read(reinterpret_cast<char*>(courses), cap * sizeof(Course));  
fin.read(reinterpret_cast<char*>(courses), size * sizeof(Course)); 
+0

は必要ありません。このエラーは 'セグメンテーションフォールト(コアダンプ)' – Norse

+0

です。あなたの質問を更新して[最小完全な検証可能な例]を作成してください(http://stackoverflow.com/help/mcve) –