2017-07-14 8 views
0

基本的にはタイトルのことです。私はchar配列だけを使用して独自の文字列クラスを作成しようとしていましたが、Visual Studioでコードを実行するときにコードが動作するうちに、gccを使用すると問題が発生します。私が手getData機能(以下見ることができます)例外は次のとおりです。string.exeに0x6262436B(ucrtbased.dll)で投げgccで例外が発生する、自分の文字列クラスを書き込もうとしています

例外:0xc0000005で:アクセス違反読み取り場所0xCCCCCCBC。

ヘッダー: 私のコードを発生

#pragma warning(disable:4996) 
#ifndef STRING_STRING_H 
#define STRING_STRING_H 

#include<iostream> 
#include<cstring> 
#include<fstream> 

class String { 
private: 
    char *data; //holds the text 
    size_t maxSize; //maximum number of chars in data 
    size_t currentSize; //current number of chars in data 

    void getData(const char *, size_t maxSize); //sets currentSize to the other char* size and 
               // copies the content of the other char* to data 
public: 
    String(); //default constructor 
    ~String(); //destructor 

    String(const String &); //copy-constructor(from String) 
    String(const char *); //copy-constructor(from char*) 

    String operator=(const String &); //operator= (from string) 
    String operator=(const char *); //operator=(from char*) 

    size_t length() const; //currentSize getter 

    void addChar(const char); //adds a char to the data array 

    void getLine(std::ifstream&,const char); // reads line till deliminator and stores it in this string object(all data previously stored is lost) 

    size_t find(const char*); //searches for text in the string and if found returns the starting position , if not found returns -1; 

    void print() const; //prints the string object to console 

    char* toChar() const; //returns a new allocated char pointer with the text inside (must be deleted afterwards) 
}; 


#endif //STRING_STRING_H 

CPP:

#include "String.h" 


String::String() { 
    currentSize = 0; 
    maxSize = 16; 
    try { 
     data = new char[maxSize]; 
     data[0] = '\0'; 
    } 
    catch (std::bad_alloc &) { 
     std::cerr << "Not enough memory" << std::endl; 
     throw; 
    } 
} 

String::~String() { 
    delete[] data; 
} 

size_t String::length() const { 
    return currentSize; 
} 

String::String(const String &other) { 
    this->maxSize = other.maxSize; 
    getData(other.data, maxSize); 
} 

String::String(const char *other) { 
    this->maxSize = strlen(other) *2; 
    getData(other, maxSize); 
} 

void String::getData(const char *dataSource, size_t maxSize) { 
    currentSize = strlen(dataSource); 
    try { 
     char *newData = new char[maxSize]; 
     delete[] data; 
     data = newData; 
     strcpy(data, dataSource); 
    } 
    catch (std::bad_alloc &) { 
     std::cerr << "Not enough memory" << std::endl; 
     throw; 
    } 
} 


String String::operator=(const String &other) { 
    if (this != &other) { 
     maxSize = other.maxSize; 
     getData(other.data, maxSize); 
    } 
    return *this; 
} 

String String::operator=(const char *other) { 
    if (this->data != other) { 
     maxSize = strlen(other) *2; 
     getData(other, maxSize); 
    } 
    return *this; 
} 

void String::addChar(const char newChar) { 
    if (maxSize == currentSize+1) { 
     maxSize *= 2; 
     getData(this->data, maxSize); 
    } 
    data[currentSize++] = newChar; 
} 

void String::getLine(std::ifstream & is, const char delim='\n') 
{ 
    char temp; 
    while (!is.eof()) 
    { 
     is.get(temp); 
     if (temp == delim) 
      break; 
     else 
      addChar(temp); 
    } 
    return; 
} 

size_t String::find(const char * text) 
{ 
    size_t currPos=-1; 
    bool found = 0; 
    for (size_t i = 0; i < currentSize; i++) 
    { 
     if (data[i] == text[0]) 
     { 
      for (size_t j = i+1; j < currentSize; j++) 
      { 
       if (data[j] == text[j - i]) 
        found = 1; 
       else 
       { 
        found = 0; 
        break; 
       } 
      } 
      if (found == 1) 
      { 
       currPos = i; 
       break; 
      } 
     } 
    } 
    return currPos; 
} 

void String::print() const 
{ 
    for (size_t i = 0; i < currentSize; i++) 
    { 
     std::cout << data[i]; 
    } 
    std::cout << std::endl; 
} 

char * String::toChar() const 
{ 
    char* text= new char[currentSize+1]; 
    for (size_t i = 0; i < currentSize; i++) 
    { 
     text[i] = data[i]; 
    } 
    text[currentSize + 1] = 0; 
    return text; 
} 
+2

はあなたが「デバッグのために '-ggdb3'フラグを追加してみてくださいgcc''使用している場合:として

String::String(const String &other) : currentSize(0), maxSize(other.maxSize), data(nullptr) { getData(other.data, maxSize); } 

同様に、char const*からコンストラクタを実装:としてあなたはコピーコンストラクタを実装することができます失敗している特定のコード行を指摘します。 16進アドレスよりも扱いがはるかに簡単です。 – Peri461

+2

デザインに関する小さなコメントがいくつかあります。 'getData'は' setData'と呼ばれるようになります。 'String(const char *)'はコピーコンストラクタではありません。コピーコンストラクタは同じ型のオブジェクトをコピーします。また、 'String'コンストラクタでは、エラーをローカルで処理するか、例外をスローします。エラーメッセージを書き出し、例外を再実行してエラーを部分的に処理しないでください。 –

+0

印刷するだけで 'bad_alloc'をキャッチする気がします。代わりにプリントがスローされる可能性があります。そうでなくても、あなたのクラスのユーザーはあなたのクラスが彼の端末で物事を印刷することを期待していないでしょう。例外がスローされたという事実は明らかであるはずです。 –

答えて

0

あなたの問題は、初期化されていないメモリ上delete []を呼び出すことによって引き起こされます。

コピーコンストラクタでは、を呼び出す前にdataメンバが初期化されていません。 getData()には、delete [] data;を使用しています。

コンストラクタ内でdatanullptrを初期化して、問題を回避することができます。

コンストラクタの本体の前で、すべての変数を適切な値に初期化することをお勧めします。例えば。

String::String(const char *other) : currentSize(0), 
            maxSize(strlen(other) *2), 
            data(nullptr) 
{ 
    getData(other, maxSize); 
} 
+0

それはそれを解決したようだと私は間違いなく良い練習として拾うべきものです。ありがとう! –

+0

@Rostislavstoyanov、あなたは大歓迎です。 –

関連する問題