Этот ответ предоставляется на основе отредактированного вопроса и различных комментариев / наблюдений в других ответах ...
Во-первых, каковы возможные состояния для pStart при вызове Next ()?
- pStart имеет значение NULL (конструктор по умолчанию или иначе установлен в NULL)
- * pStart равно '\ 0' (пустая строка в конце строки)
- *pStart - это delim (пустая строка в соседнем разделителе)
- * pStart - это что-то еще (токен непустой строки)
На данный момент нам нужно беспокоиться только о первомвариант.Поэтому я бы использовал здесь оригинальную проверку «если»:
if (pStart == NULL) { return NULL; }
Почему бы нам не беспокоиться о случаях 2 или 3?Возможно, вы захотите рассматривать соседние разделители как имеющие токен пустой строки между ними, в том числе в начале и конце строки.(Если нет, настройте по вкусу.) Цикл while будет обрабатывать это для нас, при условии, что вы также добавите проверку '\ 0' (необходимо независимо):
while (*pStart != delim && *pStart != '\0')
После того, как цикл while находится там, где вам нужнобыть осторожным.Каковы возможные состояния сейчас?
- * pStart равен '\ 0' (токен заканчивается в конце строки)
- * pStart является разделителем (токен заканчивается следующим разделителем)
Обратите внимание, что сам pStart здесь не может быть НЕДЕЙСТВИТЕЛЕН.
Вам необходимо вернуть pNextWord (текущий токен) для обоих этих условий, чтобы не отбрасывать последнеетокен (т. е. когда * pStart равен '\ 0').Код обрабатывает случай 2 правильно, но не случай 1 (исходный код опасно увеличился на pStart после '\ 0', новый код возвратил NULL).Кроме того, важно правильно сбросить pStart для случая 1, чтобы следующий вызов Next () возвратил NULL.Я оставлю точный код в качестве упражнения для читателя, так как в конце концов это домашняя работа;)
Это хорошее упражнение, чтобы наметить возможные состояния данных во всей функции, чтобы определить правильное действие для каждого из них.состояние, аналогично формальному определению базовых случаев и рекурсивных случаев для рекурсивных функций.
Наконец, я заметил, что в вашем деструкторе есть вызовы delete для pStart и pNextWord.Во-первых, для удаления массивов вам нужно использовать delete [] ptr;
(т.е. удаление массивов).Во-вторых, вы не удалили бы и pStart, и pNextWord, потому что pNextWord указывает на массив pStart.В-третьих, к концу pStart больше не указывает на начало памяти, поэтому вам потребуется отдельный элемент для хранения исходного начала для вызова delete []
.Наконец, эти массивы размещаются в стеке, а не в куче (т. Е. С использованием char var[]
, а не char* var = new char[]
), и, следовательно, их не следует удалять.Поэтому вам следует просто использовать пустой деструктор.
Еще один полезный совет - подсчитать количество вызовов new
и delete
;там должно быть одинаковое количество каждого.В этом случае у вас ноль new
вызовов и два delete
вызовов, что указывает на серьезную проблему.Если бы это было наоборот, это указало бы на утечку памяти.