class Vars{
public:
char *appData = getenv("AppData");
string datadir = strcat(appData, "\\Bob");
};cout << v.datadir;
выходы "C:\Users\Adam\AppData\Roaming\Bob\Bob"
вместо «C:\Users\Adam\AppData\Roaming\Bob"
Он всегда добавляет второй параметр дважды. Как так?
«Строка, указанная указателем, возвращаемым этой функцией, не должна изменяться программой». Изменение значения, как вы сделали (с помощью strcat), приводит к непредсказуемому поведению. Решение это просто скопировать неизменяемую данную строку в string
и сделай конкатенацию там.
Как насчет создания новой публичной функции, которая делает это:
string datadir(getenv("AppData"));
datadir += "\\Bob";
Это код до C ++ 11.
Проблема в том, что вы модифицируете память, которой не должны быть. Вы получаете указатель от getenv
, но это указывает на память, которую вы не контролируете (выделение мое).
Возвращенный указатель указывает на блок внутренней памяти, содержимое или валидность которого могут быть изменены путем дальнейших обращений к getenv (но не другими библиотечными функциями).
Строка, указанная указателем, возвращаемым этой функцией не должны быть изменены программой. Некоторые реализации систем и библиотек могут позволять изменять переменные среды с помощью определенных функций (putenv, setenv …), но такая функциональность непереносима.
По телефону strcat(appData, "\\Bob");
вы пишете \Bob
в часть памяти, которую вы не контролируете. Операционная система может решить сделать с ней любое количество вещей. Как уже указывалось @Liviu, гораздо лучше взять копию исходного значения и добавить к нему.
std::string appData( getEnv("AppData" ) );
appData += "\\Bob";