Перезапись + = Оператор C ++ - PullRequest
       12

Перезапись + = Оператор C ++

1 голос
/ 06 декабря 2011

ОБНОВЛЕНИЕ: выделенная память для новых данных str1.Ошибка памяти.

Я пытаюсь переписать метод + = для созданного мною строкового класса.

Class mystring{

public:
    friend void operator+=(mystring& str1, const mystring& str2){
        mystring temp;

        delete[] temp.data;
        temp.length = str1.length + str2.length;
        temp.data = new char[temp.length + 1];

        strcpy(temp.data, str1.data);
        strcat(temp.data, str2.data);

        delete[] str1.data;
        str1.length = temp.length;

        strcpy(str1.data, temp.data);

    }

private:
    char *data;
    int length;

}

Затем в основном классе:

mystring str1("hi");
mystring str2("matt");

str1 += str2;
cout << str1 << endl;

Эта функция работает так, как и должно быть, но я получаю ошибки памяти во всех случаях, когда я запускаю valgrind.Я не могу понять, почему это так.Если бы кто-нибудь мог дать мне какие-нибудь советы, которые были бы удивительными.

Спасибо

Ответы [ 4 ]

2 голосов
/ 06 декабря 2011

Во-первых, вы не имели в виду:

 strcat(str1.data, str1.data);

но:

 strcat(str1.data, str2.data);

Во-вторых, куда вы ожидаете str2.data? Это каракули памяти и, следовательно, ошибки valgrind. Удивило это не просто сбой.

Вам необходимо перераспределить достаточно памяти для объединенной длины, скопировать обе исходные строки и освободить str1.data, прежде чем переназначить его в новое хранилище.

На основании обновленного сообщения:

friend void operator+=(mystring& str1, const mystring& str2)
    {
        // Not using a temp mystring here, as the temp never really maintains its state as a mystring
        // I am assuming length is the length of the string, not the storage. Not the best design if you consider resizing the the string to less than the storage
        int newStringLength = str1.length + str2.length;
        char* newStorage = new char[newStringLength +  1];

        strcpy(newStorage, str1.data);
        // strcat has to scan from the start of the string; we do not need to.
        strcpy(newStorage + str1.length, str2.data);

        delete[] str1.data;

        str1.length = newStringLength ;
        str1.data = newStorage;

         // Haven't though about the case where str2 is an alias for str1.
    }
2 голосов
/ 06 декабря 2011

Вам необходимо выделить дополнительную память в str1.

Нельзя просто слепо копировать за конец массива.

1 голос
/ 06 декабря 2011
 //it is strange that operator += return void
 // usually we have T& operator += (T const&, T const&) 
  //or T& T::operator +=(T const&)
 friend void operator+=(mystring& str1, const mystring& str2){
    //make sure str1 and str2 are correclty initialzed
    str1.length = str1.length + str2.length;
    //make sure str1.data has enough memory to hold all the data
    //make sure str1.data and str2.data are null terminated strings, not binary data
    strcat(str1.data, str2.data);
}
1 голос
/ 06 декабря 2011

Вы должны выделить кучу для хранения символов и освободить кучу, когда она больше не нужна.

Примерно так:

data=new char[length+1];
...