[解決済み] c++ 解放されるポインタが割り当てられていないエラー
質問内容
c++のnew/delete、hashfunction、linkedを練習しています。
自分で練習してみました。
という構造体を持っています。
typedef struct student
{
int id;
string fName;
string lName;
student * nextStudent;
}Student;
そして、main関数でstudentの配列を定義しています。
Student * table = new Student [10];
私は、IDを受け取り、0-9に変更する独自のハッシュ関数を持っています。 私は学生を追加したい私は次のようになります。
void addStudent(int studentId, string firstName, string lastName, Student *table)
{
// using hash function, convert the id into hashed id
int hashedID = hashFunction( studentId );
Student * pointer = &table[hashedID];
while(pointer->nextStudent !=NULL){
pointer = pointer->nextStudent;
}
// once we reach to the student who has NULL in nextStudent
// add student
Student *tmp = new Student;
tmp->id = studentId;
tmp->fName = firstName;
tmp->lName = lastName;
tmp->nextStudent = NULL;
// link
pointer->nextStudent = tmp;
}
テストしてみましたが、問題ないようです。
問題は削除です。 生徒の変数は動的メモリに保存されているので deleteを使う必要があります。
以下は、私のコードです。
void deleteAll(Student *table, int len)
{
for (int i = 0; i < len; i++)
{
Student* tmp = &table[i];
// delete student info except the last one
while ( tmp -> nextStudent !=NULL){
Student* tmp2;
tmp2 = tmp;
tmp = tmp->nextStudent;
delete tmp2;
}
}
}
すべての生徒のヴァリアルを訪問し、削除を実行しました。 私の削除機能には何の問題もありません...
これが、実行後の結果です。
malloc: *** error for object 0x7f85f1404b18: pointer being freed was not allocated
何が間違っていたのか、さっぱりわかりません。 助けていただけますか?
EDIT...
皆さんから頂いたご意見の通り メイン関数に "delete [] table" を追加しました。 また、deleteAll関数の中の"delete tmp"を削除し、"delete [] table"で対応できると考えています。
それでもうまくいきません。
ところで、最初の投稿でinitTable関数を追加するのを忘れていました。 initTableはテーブルを初期化する関数です。
void initTable (Student *table, int len)
{
for (int i = 0; i < len; ++i)
{
table[i].nextStudent = NULL;
}
}
ありがとうございました。
解決方法は?
その
nextStudent
フィールドは初期化されないので、ここで作成された10個の要素はすべて未知の値を指しています。
Student * table = new Student [10];
これにより
addStudent
をループさせる。
pointer->nextStudent
が偶然 NULL 値に当たった場合、所有しないメモリを上書きします (最初の反復処理で幸運にも NULL に当たった場合を除く)。
while(pointer->nextStudent !=NULL) { ... }
student` 構造体 (なぜ typedef なのか?) には、少なくともこれを行うためのコンストラクタが必要です。
student::student() : nextStudent(NULL) { }
[ EDIT ]です。
もう一つの問題は、@JonathanPotter がコメントで適切に指摘してくれたように、10 個のそれぞれの先頭が
student
リストが
table
配列になります。それは
ではない
動的に割り当てる必要があります。
ない
を個別に削除することができます。
簡単な修正方法としては
student
デストラクタで子ノードを再帰的に削除します。
student::~student() { if(nextStudent) delete nextStudent; }
次に
deleteAll
に還元される。
void deleteAll(student *table, int len)
{
for (int i = 0; i < len; i++)
{
student *tmp = &table[i];
if(tmp->nextStudent) delete tmp->nextStudent;
}
// this leaves the dynamically allocated table[] in place
// to delete it as well, just `delete [] table;`
}
しかし、リストが大きくなると、このような再帰は実行不可能になるので、(再帰的なデストラクタを含まない)イテレーションに書き換えるのがよいでしょう。
student::~student() { }
// ...
void deleteAll(student *table, int len)
{
for(int i = 0; i < len; i++)
{
student *tmp = &table[i];
// delete student info except the *first* one
for(student *tmp2; tmp2 = tmp->nextStudent; )
{
tmp->nextStudent = tmp2->nextStudent;
delete tmp2;
}
}
// this leaves the dynamically allocated table[] in place
// to delete it as well, just `delete [] table;`
}
関連
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】LLVMで暗黙のうちに削除されたコピーコンストラクタの呼び出し
-
[解決済み】クラステンプレートの引数リストがない
-
[解決済み】識別子 "string "は未定義?
-
[解決済み】エラー:strcpyがこのスコープで宣言されていない
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】Visual Studio 2013および2015でC++コンパイラーエラーC2280「削除された関数を参照しようとした」が発生する
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。