2017-05-20 23 views
0

私は、スチューデントオブジェクトの名前を新しい名前に設定するコードを作成しようとしていますが、文字配列を作成するときにメモリリークエラーが発生します。私はそれが配列の最後に/ 0と関係があり、正しく終了していないと仮定しますが、これを正しく修正する方法はわかりません。助けてくれてありがとう。valgrindを使用しています - "無効なサイズ1の読み込み" strlen

#include "student.h" 
#include <string> 
#include <cstring> 
#include <iostream> 
using namespace std; 

Student::Student(const char * const name, int perm) { 
    this->setName(name); 
    this->setPerm(perm); 
} 

int Student::getPerm() const { 
    return this->perm; 
} 

const char * const Student::getName() const { 
    return this->name; 
} 

void Student::setPerm(const int perm) { 
    this->perm = perm; 
} 

void Student::setName(const char * const newName) { 
    this->name = new char[strlen(newName)+1]; 
    // this->name[srtlen(newName)+1] = '/0'; <---- My suggested fix, but doesn't work 
    strcpy(this->name,newName); 

} 


Student::Student(const Student &orig) { 
    this->setName(orig.getName()); 
    this->setPerm(orig.getPerm()); 
} 

Student::~Student() { 
    delete this->name; 
    this->perm = 0; 
} 

これはvalgrindのエラーです:あなたは0ターミネータを追加するために必要な

==13814== Invalid read of size 1 
==13814== at 0x4C2BA12: strlen (vg_replace_strmem.c:454) 
==13814== by 0x4F56FD6: UnknownInlinedFun (char_traits.h:267) 
==13814== by 0x4F56FD6: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (basic_string.h:456) 
==13814== by 0x401ED8: Student::toString[abi:cxx11]() const (student.cpp:64) 
==13814== by 0x401A46: main (testStudent00.cpp:14) 
==13814== Address 0x5302e8 is not stack'd, malloc'd or (recently) free'd 
==13814== 
+0

'const char *'ではなく 'std :: string'を使います。 – arboreal84

答えて

2

あなたの仮定が間違っている、strcpyの()あなたのためにそれを行うだろう。そうすることのあなたの試みはあなたが(配列のインデックスは0から始まり、覚えておいてください)割り当てられたスペースの過去0ターミネータ1つのバイトを追加し、構文も間違っている、あなたは何をする必要があります:

this->name[strlen(newName)] = '\0'; 

をしかし、修正しますあなたは

void Student::setName(const char * const newName) 
{ 
    delete [] this->name; 
    this->name = new char[strlen(newName)+1]; 
    strcpy(this->name,newName); 
} 

Student::Student(const Student &orig) : 
    name(0) { 
    this->setName(orig.getName()); 
    this->setPerm(orig.getPerm()); 
} 

Student::~Student() { 
    delete [] this->name; 
    this->perm = 0; 
} 

のような以前の文字列を、削除する必要があり、あなたのメモリリークは今、これが機能するためには、あなたもあなたのコンストラクタを修正する必要があり、名前のメンバーを初期化するコンストラクタをコピーし、それが初期化されていないポインタではありませんsetName()関数への最初の呼び出しでは、代入演算子を追加する必要があります。これにより、割り当てを適切に処理できます。

Student::Student(const char * const name, int perm) : 
    name(0) 
{ 
    this->setName(name); 
    this->setPerm(perm); 
} 

Student &operator=(const Student &orig) { 
    this->setName(orig.getName()); 
    this->setPerm(orig.getPerm()); 
} 

また、あなたも、このクラスのコピーコンストラクタ、代入演算子とデストラクタを実装する必要があり、また正しく管理に対処しないようにして、代わりに文字列を処理するあなたの現在の低レベルの道のstd::stringを使用することを検討してくださいメモリ。

+0

あなたの提案をありがとう!しかし、私は今この名前を削除しようとしましたが、実行時に大きなメモリエラーメッセージが生成されました。 –

+0

コンストラクタも更新する必要があります。新しいコードを参照してください。 – nos

+0

私はまだ同じエラーが発生しているようです。 std :: stringに変更し、ポインタの初期化を追加しました。また、if(this-> name!= NULL)を削除してからthis-> nameを削除するif文を追加しようとしましたが、うまくいきませんでした。万が一、他のアイデアはありますか? –

関連する問題