сопротивление указателя - PullRequest
3 голосов
/ 10 августа 2010

Если бы * get_ii () вернул кучу памяти, а не стековую память, эта проблема была бы устранена?

01 int *get_ii()  
02 {  
03    int ii;        // Local stack variable  
04    ii = 2;  
05    return ⅈ  
06 }  
07 main()  
08 {  
09   int *ii;  
10   ii = get_ii();  // After this call the stack is given up by the routine   
11                   // get_ii() and its values are no longer safe.  
12    
13   ... Do stuff  
14   ..  ii may be corrupt by this point.  
15 }  

Источник - http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html

спасибо

Ответы [ 6 ]

7 голосов
/ 10 августа 2010

Да.Выделение из кучи будет работать здесь.Удостоверьтесь, что где-то вы снова отпустите его, иначе вы потеряете память.

Часто умные указатели помогают с такой логикой «не забывайте».

3 голосов
/ 10 августа 2010

Вы в основном возвращаете адрес переменной, которая больше не существует (ii создается, когда функция get_ii() начинает выполняться, и существует только до выхода из функции). Любой доступ к памяти, отмеченный int *ii в main(), вызывает неопределенное поведение.

С другой стороны, память кучи выделяется, когда вы явно запрашиваете ее, и не освобождается, пока вы явно не запросите ее. Таким образом, если вы выделяете блок памяти внутри функции, вполне нормально вернуть указатель на этот блок памяти вызывающей стороне. Просто убедитесь, что документ, который отвечает за освобождение блока памяти, когда он больше не нужен!

3 голосов
/ 10 августа 2010

Справа - память из кучи (выделенная, например, с помощью malloc) будет постоянной вне области действия get_ii(). Просто убедитесь, что освободили его. Вы также можете выделить объявление ii как static int ii, и в этом случае его указатель будет существовать и за пределами get_ii().

2 голосов
/ 10 августа 2010

еще более гнусно:

std::string& makeString() //returns a reference
{ std::string str = "Dustin"; return str; }

main(){
std::string s = makeString();
//s is a dangling reference! makeString returns a reference to str, 
//but str is on the stack and goes out of scope, so we're keeping a reference to nothing
}

str (внутри makeString) находится в стеке и уничтожается при возврате makeString. устранить эту ошибку, возвращая вместо значения by-значение, что делает копию str прямо перед тем, как она выходит из области видимости.

2 голосов
/ 10 августа 2010

Проблема в вашем коде возникнет потому, что при доступе к ii в main после возврата get_ii () ваша переменная, доступ к которой осуществляется через ii, уже уничтожена.

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

0 голосов
/ 10 августа 2010

Если вы пишете код в стиле C, вам нужно передать указатель на объект и изменить объект через этот указатель. Таким образом, функция get_ii не беспокоится о том, откуда пришел объект. Вызывающая функция позаботится об этом.

Если вы пишете в стиле C ++, вы должны вернуть значение или вернуть умный указатель или взять ссылку и изменить объект с помощью этой ссылки. Или вы можете использовать стиль C и передать указатель. Некоторые авторы C ++ предпочитают проход указателя, потому что он ясно дает понять, что объект изменяется, а проход ссылки неясен.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...