Срок действия указателя после разматывания стека

В C++ указатель остается действительным после разматывания стека или нет?

5 ответов

Решение

Это зависит от того, на что указывает ваш указатель. Если он указывает на кучу памяти, он все еще остается в силе. Если он указывает на стековую память, он становится недействительным.

Это зависит от хранения указанного объекта. Если этот объект был размещен в стеке, то указатель обязательно станет недействительным - разматывание стека будет правильно уничтожать объект. Если объект был выделен в куче, указатель становится недействительным только при наличии некоторой переменной RAII, которая освобождает объект во время разматывания стека.

Рассмотрим несколько примеров:

void* f1a()
{
    void* p = malloc(10);
    return p;
}

...такой же как...

void* f1b()
{
    return malloc(10);
}

Это нормально, так как указатели находятся в куче и, следовательно, не зависят от стека, вызовов функций и программных областей. Значение указателя копируется при возврате функции.

int* f2()
{
    int x;
    return &x;  // pointer to x - about to become invalid!
}

Выше возвращает указатель на переменную x в стеке, который будет исправлен (x потерял), когда функция возвращается.

Нет. С помощью стека Разматывание всех переменных / указателей, которые объявлены в областях неупорядоченной части стека, уничтожается.

Кроме того, правило принимает во внимание Storage Type переменных.
например: A static переменная сохраняет свое значение между вызовами функций, что означает, что она не уничтожается при разматывании стека. Это связано с тем, что статические переменные хранятся не в стеке, а в BSS или сегментах данных.

Local variables(Auto storage type), созданный в стеке внутри функции, всегда будет уничтожен, когда функция вернется и размотка стека произойдет.

Указатели, выделенные с памятью в куче, не будут уничтожены при разматывании стека, поскольку они размещены в куче, а не в стеке.

Запомните одно важное правило: НИКОГДА не возвращайте указатели или ссылки на локальные переменные внутри функции. Указатель или ссылка будут содержать мусорные значения.

Просто констатировать одну дополнительную вещь, которую я считаю важной

скажем, у нас есть это заявление

obj* objptr = new obj(9) //allocate memory on heap and use constructor

если здесь происходит исключение.. кучи памяти возвращается обратно.... т.е. нет утечки памяти...

причина в том... не из-за разматывания стека... а из-за того, как новый оператор преобразуется в следующий сгенерированный код, оператор try catch реализован в новом операторе... что-то вроде этого...

void * operator new(size_t s)
{

try
{

void * ptr=new(malloc (s))sample(); //placement new
ptr->...

}

catch(..)
{
operator delete(ptr);   //<= notice here   so if an exception occur then first it         is caught here which releases the memory

}
}

однако, если в пределах объекта сделано некоторое выделение памяти, которое все еще не освобождается..

Другие вопросы по тегам