2014-09-22 15 views
-10

Добрый день, Пожалуйста, кто-нибудь может помочь? Я пытаюсь перевернуть элемент, представляющий собой массив указателей.C++ обратная строка

string::string(char *c) 
{ 
    int i =0; 
    while ((c[i] != '\0')) 
    { 
     i++; 
    } 
    _lenght= i; 
    _aString=*&c; 
} 

void string::reverse() //Requirements specify to have this argument 
{ 
      for(int i=0; i<_lenght/2; i++) 
    { 
     std::swap(_aString[i], _aString[_lenght-i-1]); 
    } 

} 

У меня возникает ошибка времени выполнения.

Это моя основная функция

int main(){ 
     string a; 
     std::cout << "a is " << a << "\n"; 
     string b("12345"); 
     string c("12345",3); 
     std::cout << "c is " << c << "\n"; 
     c = a; 
     a = b; 
     std::cout << "a is " << a << "\n"; 
     b.reverse(); 
     std::cout << "a is " << a << "\n"; 
     return 0; 
    } 

Ошибка я получаю

Необработанное исключение при 0x00fd6710 в UnisaLesson1.exe: 0xC0000005: Нарушение прав доступа месте для записи 0x00fdfd08.

Извините, я все еще новичок.

+1

'std :: reverse (_aString, _astring + length);', где длина не включает нулевой ограничитель. – juanchopanza

+1

'_aString' был установлен (как ни странно) копией указателя' c' и, вероятно, указывает на то, что было уничтожено, или (константный) строковый литерал. Но не видя, что именно 'c' указал на то, когда была создана строка, мы можем только догадываться. Попробуйте написать минимальный, но полный тестовый пример, чтобы продемонстрировать проблему. –

+0

Вам нужно выделить память в конструкторе и скопировать массив символов, который вы передали. Не забудьте освободить деструктора. –

ответ

1

Проблема заключается в том

_aString=*&c; 

который является странным способом написания

_aString=c; 

так что _aString просто указывает на какой-либо аргумент функции был; этот класс не управляет памятью для строки (как это делает std::string), но относится к внешней строке, управляемой в другом месте.

В тестовом примере эта строка является строковым литералом, который не поддается изменению. Поэтому, пытаясь изменить его, как это делает reverse, дает неопределенное поведение; если вам повезет, нарушение прав доступа; если вам не повезло, повреждение данных или какое-то другое нежелательное поведение во время работы.

Если ваш класс должен управлять памятью, тогда он должен будет выделить его в конструкторе. Предполагая, что это назначение является упражнением в управлении памятью (в противном случае, просто использовать std::string), вы хотите что-то вроде

_aString = new char[_lenght]; 
std::copy(c, c+_lenght, _aString); 

и не забывайте Rule of Three:

  • деструктор, чтобы освободить память с delete [] _aString
  • конструктор копирования, удаленный для предотвращения копирования или реализованный для выделения нового буфера;
  • Оператор копирования-назначения, удаленный для предотвращения копирования или реализованный для копирования в существующий буфер после изменения размера, если необходимо.

Вы также можете рассмотреть вопрос о правописании _lenght по номеру _length.

Смежные вопросы