Взглянув на ответ Enhardened, они заявляют, что их предпоследнее выражение не будет соответствовать последовательностям с одним символом между ними. Существует простой способ исправить это, не заглядывая вперед и не заглядывая назад, и это означает, что символ начала и конца должен быть заменен символом границы. Это позволяет вам сопоставлять границы слов, которые включают начало / конец. Таким образом, соответствующее выражение должно быть:
(?:[^x]|\b)(x{n}|x{m})(?:[^x]|\b)
Как вы можете видеть здесь: https://regex101.com/r/oC5oJ4/2 .
Нет, этот код в порядке и не будет утечки памяти.
Вам нужно использовать delete [] только один раз, потому что вы использовали только один new для выделения области для памяти, даже если есть два указателя на ту же самую память.
Каждому новому
должно соответствовать одно и только одно соответствие delete
. Если вы удалите другой указатель, вы нарушите это правило.
Здесь вы просто скажете, что блок памяти, выделенный new char [256]
, будет указываться pointer1
и pointer2
одновременно.
Если вы написали бы оператор delete [] pointer2;
после него, это было бы утечкой памяти.
Простое правило: вам нужно столько delete
ов, сколько new
ов. Еще лучше использовать что-то вроде умного указателя или контейнера, чтобы позаботиться об этом за вас.
И еще один незначительный момент: pointer2
становится "висящим указателем", как только вы вызываете delete
на pointer1
.
Это не утечка, но проблема. pointer2
указывает на неизвестно что, как только вы удалите pointer1
. Это так называемый «висячий указатель». Его использование может в лучшем случае вызвать segfault, а в худшем - вызвать таинственное искажение данных во всем, что в конечном итоге будет выделено в том же месте.
Хотя утечки памяти не происходит, но если вы хотите быть явным, вы должны установить для point1
и point2
значение NULL (и инициализировать их так тоже.)
Кроме того, рассмотрите возможность использования boost :: shared_ptr <>
из библиотек Boost. Это лучшая вещь после нарезанного хлеба.
typedef boost::shared_ptr<TypeX> StrRef;
foo() {
StrRef pointer1(new TypeX);
while(something) {
StrRef pointer2 = pointer1;
// do stuff
}
return;
}
Данные ( TypeX
) будут удалены, когда последний указатель на них выйдет за пределы области видимости. Вы можете сделать что-то подобное со встроенным типом auto_ptr <>
, если вам не нужен счетчик ссылок:
typedef auto_ptr<TypeX> StrRef;
foo() {
StrRef pointer1(new TypeX);
while(something) {
TypeX * pointer2 = pointer1.get();
subroutine(pointer2);
if (condition) return;
}
return;
}
Каждый раз, когда pointer1
выходит за пределы области видимости, он удаляет данные. Преимущество этого заключается в том, что вам не нужно помнить, что нужно помещать удаление перед оператором return внизу, и если pointer1
выходит из области видимости по любой другой причине (т.е. возврат из середины цикла , или subroutine ()
генерирует исключение, тогда данные все равно будут освобождены должным образом.
Я не тестировал этот код, поэтому вам придется проверить документацию для auto_ptr < >
и boost :: shared_ptr <>
самостоятельно.
Я настоятельно рекомендую как можно больше использовать библиотеки Boost. Он написан профессионалами, это в основном промежуточная область для расширений C ++.
Используйте Delete только тогда, когда вы использовали New
Хорошая практика - установить для pointer2 значение NULL, но у вас не будет утечки памяти, если вы этого не сделаете
Нет, вам не нужно удалять[] указатель2, потому что вы не выделили для него память!
Оператор pointer2 = pointer1
заставляет pointer2
указывать на тот же адрес памяти, что и pointer1
, не выделяя для него никакой дополнительной памяти.
Вот пробел в вашем мышлении: Вы не удаляете указатели - вы удаляете память. Вы просто используете указатель, чтобы определить блок памяти, который нужно освободить. Поскольку две переменные указывают на одну и ту же память, удаление одной из них эквивалентно удалению другой. Другими словами, удаление обеих переменных равносильно удалению одной из них дважды - что, очевидно, неправильно.
delete
удаляет память, выделенную новым
. Поскольку у вас только один новый
, вам нужен только один delete
.