I cant figure out how to have my pointer argv maintain its memory that I dynamically allocate in another function called parseCommand. I need to call parseCommand, allocate the needed memory for the parsed strings and then return to main and print the strings my pointer points to. I would just have parseCommand return the pointer but I have to return the number of arguments found. I haven't really worked to much with c pointers so they are giving me some trouble here. So how do I go about having my pointer maintain its memory between functions?
Main:
int main()
{
char **argv, str[] = "ls -l -s -r -h file";
int argc;
argc = parseCommand(str, &argv);
int i;
printf("Arguments in argv: \n");
for (i = 0; i < argc; i++) //I want to output the arguments
printf("%s \n", argv[i]); //stored in pointer argv
return 0;
}
My parse function that dynamically allocates memory for my pointer so it can store the arguments in str.
Parse Command:
int parseCommand(char *str, char ***args)
{
int i = -1, prevPos = 0, argc = 0, argl = 0, argCount = 0;
argCount = getArgCount(str); //Returns 6
args = malloc(sizeof(char*) * (argCount + 1)); /*Allocates memory for args in amount of arguments str holds*/
if (!args){printf("Allocation failed");} /*Checks if there was a problem with memory allocation*/
do
{
i++;
if (str[i] == ' ' || str[i] == '\n' || str[i] == '\0')
{
argl = (i + 1) - prevPos; /*argl holds the length of the argument*/
args[argc] = malloc(sizeof(char) * argl); /*Allocates memory for args in the size of the argument*/
if (!args[argc]){printf("Allocation failed");} /*Checks if there was a problem with memory allocation*/
memcpy(args[argc], str + prevPos, argl); /*Copys the argument of the string into args*/
args[argc][argl - 1] = '\0'; /*Assigns \0 at the end of the string*/
argc++;
prevPos = i + 1;
}
} while (str[i] != '\0');
args[argc] = malloc(sizeof(char)); /*Allocates one last piece of memory for args*/
args[argc][0] = (char *)NULL; /*Sets this new piece of memory to NULL*/
printf("Arguments in args: \n");
for (i = 0; i < argc; i++)
printf("%s \n", args[i]);
return argCount;
}
In parseCommand()
, args
is char ***
but you're treating it like char **
. You need to dereference it once to get the char **
that you'll have in main()
. For example, this:
args = malloc(sizeof(char*) * (argCount + 1));
..should be:
*args = malloc(sizeof(char*) * (argCount + 1));
And this:
args[argc] = malloc(sizeof(char) * argl);
..should be:
(*args)[argc] = malloc(sizeof(char) * argl);
and these lines:
memcpy(args[argc], str + prevPos, argl);
args[argc][argl - 1] = '\0';
..should be:
memcpy((*args)[argc], str + prevPos, argl);
(*args)[argc][argl - 1] = '\0';
etc.
args
from parseCommand()
does not point at the array of char *
for the argument strings -- it points to argv
from main()
, and that points to the array of char *
for the argument strings... so you need to dereference args
once before using it.