Срок действия указателя после разматывания стека - PullRequest
1 голос
/ 25 апреля 2011

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

Ответы [ 5 ]

2 голосов
/ 25 апреля 2011

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

1 голос
/ 25 апреля 2011

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

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 потерян), когда функция вернется.

1 голос
/ 25 апреля 2011

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

1 голос
/ 25 апреля 2011

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

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

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

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

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

0 голосов
/ 26 сентября 2013

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

скажем, у нас есть это утверждение

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

}
}

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

...