Pointer or reference to stack variable leaving scope

Указатель на локальную переменную оставляет переменную scope

Описание

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

  • Функция возвращает указатель на локальную переменную.

  • Функция выполняет присвоение globPtr = &locVar. globPtr глобальная переменная указателя и locVar локальная переменная.

  • Функция выполняет присвоение *paramPtr = &locVar. paramPtr параметр функции то есть, например, int** указатель и locVar локальный int переменная.

  • Метод C++ выполняет присвоение memPtr = &locVar. memPtr элемент данных указателя класса, которому принадлежит метод. locVar переменная локальная переменная к методу.

  • (C++ 11 и позже) функция возвращается, лямбда-выражение возражают что локальные переменные получений функции ссылкой.

Дефект также применяется к выделенному использованию памяти 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,

auto createAdder(int amountToAdd) {
  int addThis = amountToAdd;
  auto adder = [&] (int initialAmount) {
      return (initialAmount + addThis);
  };
  return adder;
}
 
void func() {
  auto AddByTwo = createAdder(2);
  int res = AddByTwo(10);
}

В этом примере, createAdder функция задает лямбда-выражение adder это получает локальную переменную addThis ссылкой. Осциллограф addThis ограничивается createAdder функция. Когда объект, возвращенный createAdder называется, ссылка на переменную addThis получен доступ вне его осциллографа. Когда получено доступ таким образом, значение addThis isundefined.

Коррекция – получает локальные переменные копией в лямбда-выражении вместо ссылки

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

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

auto createAdder(int amountToAdd) {
  int addThis = amountToAdd;
  auto adder = [=] (int initialAmount) {
      return (initialAmount + addThis);
  };
  return adder;
}
 
void func() {
  auto AddByTwo = createAdder(2);
  int res = AddByTwo(10);
}

Информация о результате

Группа: Статическая память
Язык: C | C++
Значение по умолчанию: На для рукописного кода, прочь для сгенерированного кода
Синтаксис командной строки: LOCAL_ADDR_ESCAPE
Удар: высоко
ID CWE: 562, 825
Введенный в R2015b