Выход адреса автоматического объекта
Указатель или ссылка, чтобы сложить переменный осциллограф отъезда происходят, когда указатель или ссылка на локальную переменную оставляют осциллограф переменной. Например:
Функция возвращает указатель на локальную переменную.
Функция выполняет присвоение globPtr = &locVar
. globPtr
является глобальной переменной указателя, и locVar
является локальной переменной.
Функция выполняет присвоение *paramPtr = &locVar
. paramPtr
является параметром функции то есть, например, указатель int**
и locVar
являются локальной переменной int
.
Метод C++ выполняет присвоение memPtr = &locVar
. memPtr
является элементом данных указателя класса, которому принадлежит метод. locVar
является переменной локальной переменной к методу.
Дефект также применяется к выделенному использованию памяти функции alloca
. Дефект не применяется к статическим, локальным переменным.
Локальные переменные выделяются адрес на стеке. Если осциллограф локальной переменной заканчивается, этот адрес доступен для повторного использования. Используя этот адрес, чтобы получить доступ к значению локальной переменной вне переменной scope может вызвать неожиданное поведение.
Если указатель на локальную переменную оставляет осциллограф переменной, Polyspace® Bug Finder™ подсвечивает дефект. Дефект появляется, даже если вы не используете адрес, сохраненный в указателе. Для удобного в сопровождении кода это - хорошая практика, чтобы не позволить указателю оставлять переменную scope. Даже если вы не используете адрес в указателе теперь, кто-то еще использующий вашу функцию может использовать адрес, вызывая неопределенное поведение.
Не позволяйте указателю или ссылке на локальную переменную оставлять переменную scope.
void func2(int *ptr) {
*ptr = 0;
}
int* func1(void) {
int ret = 0;
return &ret ;
}
void main(void) {
int* ptr = func1() ;
func2(ptr) ;
}
В этом примере func1
возвращает указатель на локальную переменную ret
.
В main
ptr
указывает на адрес локальной переменной. Когда к ptr
получают доступ в func2
, доступ недопустим, потому что осциллограф ret
ограничивается func1
,
Использование автоматической переменной как putenv
- аргумент функции семейства происходит, когда аргумент putenv
- функция семейства является локальной переменной с автоматической длительностью.
Функциональный putenv(char *string)
вставляет указатель на свой переданный аргумент в массив среды, вместо того, чтобы делать копию аргумента. Если аргумент является автоматической переменной, ее память может быть перезаписана после того, как функция, содержащая вызов putenv()
, возвращается. Последующий вызов getenv()
от другой функции возвращает адрес переменной out-of-scope, которая не может быть разыменована по закону. Эта переменная out-of-scope может заставить переменные окружения брать неожиданные значения, заставлять программу прекращать отвечать или позволять произвольные уязвимости выполнения кода.
Используйте setenv()
/unsetenv()
, чтобы установить и сбросить переменные окружения. Также используйте putenv
- аргументы функции семейства с динамически выделенной памятью, или, если ваше приложение не имеет никаких требований повторной входимости, аргументов со статической длительностью. Например, одно выполнение потока без рекурсии или прерываний не требует повторной входимости. Это не может быть названо (повторно введенное) во время своего выполнения.
putenv()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE1024 1024
void func(int var)
{
char env[SIZE1024];
int retval = sprintf(env, "TEST=%s", var ? "1" : "0");
if (retval <= 0) {
/* Handle error */
}
/* Environment variable TEST is set using putenv().
The argument passed to putenv is an automatic variable. */
retval = putenv(env);
if (retval != 0) {
/* Handle error */
}
}
В этом примере sprintf()
хранит символьную строку TEST=var
в env
. Значение переменной окружения TEST
затем установлено к var
при помощи putenv()
. Поскольку env
является автоматической переменной, значение TEST
может измениться, если func()
возвращается.
static
для аргумента putenv()
Объявите env
как переменную статической длительности. Ячейка памяти env
не перезаписывается на время программы, даже после того, как func()
возвратится.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE1024 1024 void func(int var) { /* static duration variable */ static char env[SIZE1024]; int retval = sprintf(env,"TEST=%s", var ? "1" : "0"); if (retval <= 0) { /* Handle error */ } /* Environment variable TEST is set using putenv() */ retval=putenv(env); if (retval != 0) { /* Handle error */ } }
setenv()
, чтобы установить значение переменной окруженияЧтобы установить значение TEST
к var
, используйте setenv()
.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define SIZE1024 1024 void func(int var) { /* Environment variable TEST is set using setenv() */ int retval = setenv("TEST", var ? "1" : "0", 1); if (retval != 0) { /* Handle error */ } }
Разрешимость: неразрешимый |
[1] Выписки из стандарта "Техническая характеристика ISO/IEC TS 17961 - 2013-11-15" воспроизводятся с соглашением о AFNOR. Только исходный и полный текст стандарта, как опубликовано Выпусками AFNOR - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.