Использование to strcpy() для получения частей char* вызывает сбой программы
Я пытаюсь взять биты из символа *, а затем сохранить его на карте. Я использую strcpy & strncpy для этого, но моя программа падает, когда я использую strncpy (она компилируется, но падает во время выполнения).
Почему происходит сбой моей программы и как я могу успешно получить биты из char* и сохранить их на карте?
РЕДАКТИРОВАТЬ: после принятия совета я инициализировал char*, но он все еще падает?
// I did the following
char* variable = "";
char* value = "";
map <string, string> GetEvironmentVariablesEx()
{
map <string, string> envVariables;
char* environVar = GetEnvironmentStrings();
char* pos = strchr( environVar, '\0' );
// This is what environVar contains: environVar = "=::=::\0APPDATA=c:/users/user1/desktop\0OS=windowsNT\0\0"; // note the string is double null terminated
// Skip over the "=::=::\0" of the environVar string
if ( pos != NULL ) { environVar = ++pos; pos = strchr( environVar, '\0' ); }
else return envVariables;
while ( true )
{
char* delim = strchr( environVar, '=' );
char* variable;
char* value;
if ( delim == NULL ) { printf("Environment variable string is badly formatted"); break; }
// The crash occurs at the below line: the crash occurs at runtime
strncpy( variable, environVar, strlen(delim) );
strcpy( value, environVar+strlen(delim) );
printf( "Variable is: %s = %s \n", variable, value );
envVariables.insert( pair<string, string>(string(variable), string(value)) );
environVar = ++pos;
// find the "\0\0" that identifies the end of environVar
if ( pos != NULL && *pos == 0 ) { break; }
pos = strchr( environVar, '\0' );
}
FreeEnvironmentStrings( environVar );
return envVariables;
}
3 ответа
Авария происходит из-за следующего:
char* variable; // un allocated or uninitialized
char* value; // un allocated or uninitialized
Лучший способ - это использовать std::string
, например
std::string variable, value;
variable = environVar;
value = environVar + strlen(delim);
На боковой ноте, вы должны return
(или обработать как ошибку) из функции, когда вы сталкиваетесь:
if ( delim == NULL )
Я вижу, что вы делаете String-Copy (strncpy
) в variable
,
variable
объявлен как char*
, но я не вижу, чтобы вы выделяли для него какую-либо память или иным образом присваиваете значение variable
,
В следствии, variable
содержит случайный адрес памяти, и вы копируете часть вашего environVar
в неизвестный кусок памяти, в результате чего происходит сбой.
Чтобы это исправить, вы должны использовать malloc
выделить немного памяти для variable
перед звонком strncpy
,
РЕДАКТИРОВАТЬ: после вашего недавнего изменения, ваш код теперь имеет:
char* variable = "";
и позже:
char* variable;
Вторая декларация variable
по- прежнему неинициализирован и скрывает (затеняет) первое объявление. Таким образом, вы вообще не устранили проблему.
Когда я предлагаю использовать malloc
выделить память, вот о чем я говорю:
variable = malloc(strlen(delim));
strncpy( variable, environVar, strlen(delim) );
Обратите внимание, что каждый раз, когда вы выделяете память, например, с malloc
Вы должны быть готовы освободить его, когда закончите. В противном случае ваша программа будет иметь утечку памяти.
char* variable;
char* value;
Вам необходимо динамически назначить память или сделать ее массивом в стеке, прежде чем копировать в нее какие-либо данные. Это всего лишь указатели, и у них нет памяти для ввода данных.
Чтобы преобразовать char * в строку для добавления в карту, используйте:
char* data = ...;
int size = ...;
std::string myString(data, size);
РЕДАКТИРОВАТЬ: в идеале, вы должны использовать vector
управлять вашей строкой символов без суеты динамического распределения или незнания максимального размера строки символов перед рукой.
vector<char>value;
vector<char>variable;
При этом вам больше не нужно беспокоиться о размерах, сам вектор заботится о автоматическом увеличении размера.