РЕДАКТИРОВАТЬ: Pastebin ссылки на весь код в нижней части
для моего курса CS215 мне дали класс String215, который является базовым строковым классом, помогающим понять динамическое распределение памяти и арифметику указателей с массивами символов.
Класс был дан мне в очень простой форме скелета с прототипами, но без реализаций, вместе с тестовой функцией для тестирования моих реализаций. Я не могу использовать любые функции 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
Я вполне уверен, что это как-то связано с моим очень плохим управлением памятью. Я знаю, что это не так уж и много, но я боролся с этим часами и не могу этого понять.
Вот вставка файла .cpp и .h для этой программы
string215.cpp: http://pastebin.com/Xh2SvDKJ
string215.h: http://pastebin.com/JfAJDEVN
Любая помощь с благодарностью!
Спасибо,
RAW-BERRY
Вы меняете data
указатель перед delete[]
, Вам нужно delete[]
точно такое же значение, которое вы получили от new[]
,
Кроме того, вы увеличиваете output
указатель str_len(data)+suffix.length()
раз, и вы принимаете это обратно str_len(data) + suffix.length() + 1
,
Я бы использовал отдельные переменные для итерации, чтобы решить эти проблемы.
Вы увеличиваете output
именно так str_len(data) + suffix.length()
раз. Обратите внимание, что вы не увеличиваете output
после *output = '\0';
,
Итак, чтобы вернуться к началу, вы должны использовать:
output -= (str_len(data) + suffix.length());
Кстати, часть кода не очень эффективна. Например, getchar
использует цикл вместо простого возврата data[index]
, Ты используешь getchar
в append
Это означает, что производительность невелика.
РЕДАКТИРОВАТЬ: Как говорит ZCH, вы используете delete[] data
после модификации data
, но учтите, что еще до этого вы используете str_len(data)
после модификации data
(когда принимаете решение, сколько байтов нужно пропустить), поэтому расчет неверен (и мое предложение выше также неверно, потому что str_len(data)
сейчас ноль).
Поэтому я думаю, что ваша проблема с линией
for(int x = 0; x < str_len(data); x++) {
Обратите внимание, что размер «данных» меняется на каждой итерации цикла. Увеличивая значение «x», вы уменьшаете длину «данных». Предположим, что «data» — это строка, содержащая «hello»: в первой итерации цикла x = 0 и str_len (data) = 5; во второй итерации x = 1 и str_len (data) = 4. Таким образом, цикл for выполняется вдвое меньше, чем нужно, и «данные» не заканчивают указанием на конец строки данных.