exponenta event banner

Доступ к объекту с временным временем жизни

Операции чтения или записи для объекта не определены

Описание

Этот дефект возникает при попытке чтения или записи в объект с временным временем жизни, возвращаемым вызовом функции. В структуре или объединении, возвращаемых функцией и содержащих массив, элементы массива являются временными объектами. Время жизни временных объектов заканчивается:

  • Когда полное выражение или полный декларатор, содержащий вызов, заканчивается, как определено в C11 Standard.

  • После следующей точки последовательности, как определено в стандартах C90 и C99. Точка последовательности - это точка в выполнении программы, в которой все предыдущие оценки завершены и последующая оценка еще не начата.

Для кода C++ при доступе к объекту с временным временем жизни возникает дефект только при записи в объект с временным временем жизни.

Если временный объект времени жизни возвращается по адресу, дефекты не возникают.

Риск

Изменение объектов с временным временем жизни является неопределенным поведением и может привести к ненормальному завершению программы и проблемам с переносимостью.

Зафиксировать

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

Примеры

развернуть все

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#define SIZE6 6

struct S_Array
{
    int t;
    int a[SIZE6];
};

struct S_Array func_temp(void);

/* func_temp() returns a struct value containing
* an array with a temporary lifetime.
*/
int func(void) {
 
/*Writing to temporary lifetime object is
 undefined behavior
 */
    return ++(func_temp().a[0]); 
}

void main(void) {
    (void)func();
}

В этом примере: func_temp() возвращает по значению структуру с элементом массива a. Этот член имеет временный срок службы. Приращение является неопределенным поведением.

Исправление - назначение возвращаемого значения локальной переменной перед записью

Одной из возможных корректировок является назначение возврата вызова func_temp() локальной переменной. Содержимое временного объекта a копируется в переменную, которую можно безопасно увеличить.

 #include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#define SIZE6 6

struct S_Array
{
    int t;
    int a[SIZE6];
};

struct S_Array func_temp(void);

int func(void) {

/* Assign object returned by function call to 
 *local variable
 */
    struct S_Array s = func_temp(); 

/* Local variable can safely be
 *incremented
 */
    ++(s.a[0]);                                           
    return s.a[0];
}

void main(void) {
    (void)func();
}

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

Группа: Программирование
Язык: C | C++
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: TEMP_OBJECT_ACCESS
Воздействие: Низкий
CWE ID: 825
Представлен в R2018a