I'm attempting to create an array of strings that represent the directories stored in the PATH variable. I'm writing this code in C, but I'm having trouble getting the memory allocation parts working.
char* shell_path = getenv ("PATH");
char* tok = strtok (shell_path, SHELL_PATH_SEPARATOR);
int number_of_tokens = 0, i = 0;开发者_Go百科
while (tok != NULL)
{
number_of_tokens++;
}
Shell_Path_Directories = malloc (/* This is where I need some help */);
shell_path = getenv ("PATH");
tok = strtok (shell_path, SHELL_PATH_SEPARATOR);
while (tok != NULL)
{
Shell_Path_Directories[i++] = tok;
tok = strtok (NULL, SHELL_PATH_SEPARATOR);
}
The issue I'm having is that I can't think of how I can know exactly how much memory to allocate.
I know I'm tokenizing the strings twice, and that it's probably stupid for me to be doing that, but I'm open to improvements if someone can figure out a better way to do this.
Just to give you basically the same answer as user411313's in a different dialect:
char* shell_path = getenv ("PATH");
/* Copy the environment string */
size_t const len = strlen(shell_path)+1;
char *copyenv = memcpy(malloc(len), shell_path, len);
/* start the tokenization */
char *p=strtok(copyenv,SHELL_PATH_SEPARATOR);
/* the path should always contain at least one element */
assert(p);
char **result = malloc(sizeof result[0]);
int i = 0;
while (1)
{
result[i] = strcpy(malloc(strlen(p)+1), p);
p=strtok(0,SHELL_PATH_SEPARATOR);
if (!p) break;
++i;
result = realloc( result, (i+1)*sizeof*result );
}
You can do:
Shell_Path_Directories = malloc (sizeof(char*) * number_of_tokens);
Also the way you are counting the number_of_tokens
is incorrect. You need to call the strtok
again in the loop passing it NULL
as the 1st argument:
while (tok != NULL) {
number_of_tokens++;
tok = strtok (NULL, SHELL_PATH_SEPARATOR);
}
Since you've counted the number of tokens already, you can use that as the number of pointers to char to allocate:
char **Shell_Path_Directories = malloc(number_of_tokens * sizeof(char *));
Then you have one more minor issue: you're using strtok
directly on the string returned by getenv
, which leads to undefined behavior (strtok
modifies the string you pass to it, and you're not allowed to modify the string returned by getenv
, so you get undefined behavior). You probably want to duplicate the string first, then tokenize your copy instead.
You should not change the getenv-return pointer, safer you make a copy. With strtok you can destroy the content of your environment table.
char* shell_path = getenv ("PATH");
char *p,*copyenv = strcpy( malloc(strlen(shell_path)+1), shell_path );
char **result = 0;
int i = 0;
for( p=strtok(copyenv,SHELL_PATH_SEPARATOR); p; p=strtok(0,SHELL_PATH_SEPARATOR) )
{
result = realloc( result, ++i*sizeof*result );
strcpy( result[i-1]=malloc(strlen(p)+1), p );
}
精彩评论