2013-03-02 5 views
0

EDIT: Pastebin ссылки на полностью кода в нижнейОшибка отладки! манипуляция Строка с использованием арифметики с указателями

для моей CS215 я, конечно, был дан класс под названием String215, который является базовым классом строки, чтобы помочь в понимании динамическое распределение памяти и арифметика указателя с массивами char.

Класс был предоставлен мне в очень простой форме скелета с прототипами, но не с реализациями, а также с тестовой функцией для проверки моих реализаций. Я НЕ МОЖЕТ использовать любые функции C String в этом назначении.

Часть программы, которая беспокоит, - это функция добавления, которая просто добавляет объект string215 параметра в конец текущего объекта string215.

// Add a suffix to the end of this string. Allocates and frees memory. 
void string215::append(const string215 &suffix) 
{ 
    char *output = new char[str_len(data)+suffix.length()+1]; 
    for(int x = 0; x < str_len(data); x++) { 
      *output = *data; 
     output++; 
     data++; 
    } 

    for(int x = 0; x < suffix.length(); x++) { 
     *output = suffix.getchar(x); 
     output++; 
    } 
    *output = '\0'; 
    output -= (str_len(data)+suffix.length()+1); 
    delete[] data; 
    data = output; 
} 

Эта часть кода проверяется в 13-тест функции тестирования, как показано здесь:

string215 str("testing"); 

... 

// Test 13: test that append works in a simple case. 
curr_test++; 
string215 suffix("123"); 
str.append(suffix); 
if (strcmp(str.c_str(), "testing123") != 0) { 
    cerr << "Test " << curr_test << " failed." << endl; 
    failed++; 
} 

Вот описание класса дописывания:

Добавьте суффикс до конца этой строки. Выделяет новый, больший массив; копирует старое содержимое, за которым следует суффикс, в новый массив; затем освобождает старый массив и обновляет указатель на новый.

Моей программа прерывается в самом конце выполнения функции дописывания с сообщением об ошибке:

Debug Assertion Failed! 

Program: [Source path]\dbgdel.cpp 
Line: 52 

Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 

... 

Abort || Retry || Ignore 

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

Вот Pastebin из .cpp и .h файл для этой программы

string215.cpp: http://pastebin.com/Xh2SvDKJ

string215.h: http://pastebin.com/JfAJDEVN

Любая помощь на всех очень ценится!

Спасибо, RAW-BERRY

ответ

0

Вы увеличиваете output точно str_len(data) + suffix.length() раз. Обратите внимание, что вы не увеличиваете output после *output = '\0';.

Так, чтобы вернуться к началу, вы должны использовать:

output -= (str_len(data) + suffix.length()); 

Кстати, некоторые из кода не очень эффективные. Например, getchar использует цикл вместо простого возврата data[index]. Вы используете getchar в append, что означает, что производительность невелика.

EDIT: Как говорит ПНУ, вы используете delete[] data после изменения data, но учтите, что даже до того, что вы используете str_len(data) после изменения data (при принятии решения о том, сколько байт идти пропустить назад), поэтому расчет неверно (и мое предложение выше также неверно, потому что str_len(data) теперь равен нулю).

+0

Удивительное спасибо! Я понял мою оригинальную проблему, теперь она идет к следующей! Повреждение кучи T_T – user2125518

0

Вы меняете указатель data до delete[]. Вам нужно delete[] точно такое же значение вы получили от new[].

Кроме того, вы увеличите значение на output на указателе str_len(data)+suffix.length() и верните его на str_len(data) + suffix.length() + 1.

Я бы использовал отдельные переменные для итерации для решения этих проблем.

+0

Ahhh, это имеет смысл! Проверка локальных переменных, когда я выполняю выполнение функции добавления, подтверждает, что вывод содержит правильное значение, так что это хорошо! Тем не менее, теперь у меня появляется ошибка HEAP CORRUPTION DETECTED, которая из того, что я могу сказать, означает, что я не правильно распределял память? Нужно ли перераспределять память для данных? Должен ли я просто написать новый пост? – user2125518

0

Так что я думаю, что ваша проблема с линией

for(int x = 0; x < str_len(data); x++) { 

Обратите внимание, что размер «данных» меняется на каждой итерации цикла. По мере увеличения «x» вы уменьшаете длину «данных». Предположим, что «данные» - это строка, содержащая «привет»: на первой итерации цикла x = 0 и str_len (data) = 5; во второй итерации x = 1 и str_len (data) = 4. Таким образом, цикл for выполняется в два раза больше, чем вам нужно, и «данные» не заканчиваются, указывая на конец строки данных

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