Использование to strcpy () для получения частей char * вызывает сбой программы - PullRequest
0 голосов
/ 13 июня 2011

Я пытаюсь взять биты с символа * и сохранить их на карте.Для этого я использую strcpy & strncpy, но моя программа падает, когда я использую strncpy (он компилируется, но падает во время выполнения).

Почему происходит сбой моей программы и как я могу успешно получить биты из символа *сохранить их на карте?

РЕДАКТИРОВАТЬ: после получения совета я инициализировал символ *, но он все еще падает?

// 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 ]

3 голосов
/ 13 июня 2011

Сбой из-за следующего:

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 )
1 голос
/ 13 июня 2011

Я вижу, что вы делаете String-Copy (strncpy) в variable.

variable объявлен как char*, но я не вижу, чтобы вы выделяли для него какую-либо память или иным образом присваивали значение variable.

В результате variable содержит случайный адрес памяти, и вы копируете часть вашего environVar в неизвестный фрагмент памяти, что приводит к сбою.

Чтобы исправить это, вы должны использовать malloc, чтобы выделить часть памяти для variable перед вызовом strncpy.

РЕДАКТИРОВАТЬ : после вашего недавнего изменения ваш код теперь имеет:

char* variable = ""; 

и позже:

char* variable;

Второе объявление variable является все еще неинициализированным и скрывает ( shadows ) первое объявление. Таким образом, вы вообще не устранили проблему.

Когда я предлагаю использовать malloc для выделения памяти, я говорю об этом:

variable = malloc(strlen(delim)); 
strncpy( variable, environVar, strlen(delim) );  

Обратите внимание, что каждый раз, когда вы выделяете память, например, с помощью malloc, вы должны быть готовы освободить ее, когда закончите. В противном случае ваша программа будет иметь утечку памяти.

0 голосов
/ 13 июня 2011
char* variable;  
char* value; 

Вам необходимо динамически распределить память или сделать ее массивом в стеке, прежде чем копировать в нее какие-либо данные. Это просто указатели, и у них нет памяти для ввода данных.

Чтобы преобразовать char * в строку для добавления в карту, используйте:

char* data = ...; 
int size = ...; 
std::string myString(data, size); 

РЕДАКТИРОВАТЬ: В идеале, вы должны использовать vector для управления вашей строкой символов без хлопот динамического распределения или незнания максимального размера строки символов перед рукой.

vector<char>value;    
vector<char>variable;

При этом вам больше не нужно беспокоиться о размерах, сам вектор позаботится о автоматическом увеличении размера.

...