ПроблемаИзменение внутреннего буфера, возвращаемого неназначенной стандартной функцией, происходит в следующих случаях:
Неназначенная стандартная функция возвращает указатель.
Выполняется попытка записи в память, на которую указывает указатель.
неназначенные стандартные функции, возвращающие const-квалифицированный указатель на внутренний буфер include getenv, getlogin, crypt, setlocale, localeconv, strerror и другие.
РискИзменение внутреннего буфера, возвращаемого неназначенной стандартной функцией, может привести к следующим проблемам:
Возможно, что изменение не будет успешным или изменит другие внутренние данные.
Например, getenv возвращает указатель на значение переменной среды. При изменении этого значения изменяется среда процесса и повреждаются другие внутренние данные.
Даже в случае успешного изменения возможно, что последующий вызов той же стандартной функции не вернет измененное значение.
Например, можно изменить значение переменной среды, getenv возвращает. Если вызывается другой процесс, поток или обработчик сигналов setenvизмененное значение перезаписывается. Следовательно, последующий вызов getenv не возвращает измененное значение.
ЗафиксироватьИзбегайте изменения внутреннего буфера с помощью указателя, возвращаемого функцией.
Пример - Изменение getenv Возвращаемое значение#include <stdlib.h>
#include <string.h>
void printstr(const char*);
void func() {
char* env = getenv("LANGUAGE");
if (env != NULL) {
strncpy(env, "C", 1);
printstr(env);
}
}В этом примере первый аргумент strncpy - возвращаемое значение из неназначенной стандартной функции getenv. Поведение может быть неопределенным, поскольку strncpy изменяет этот аргумент.
Исправление - Копировать возвращаемое значение getenv и Изменить копиюОдним из возможных решений является копирование возвращаемого значения getenv и передать копию в strncpy функция.
#include <stdlib.h>
#include <string.h>
enum {
SIZE20 = 20
};
void printstr(const char*);
void func() {
char* env = getenv("LANGUAGE");
if (env != NULL) {
char env_cp[SIZE20];
strncpy(env_cp, env, SIZE20);
strncpy(env_cp, "C", 1);
printstr(env_cp);
}
}