So this is more a plea for explanations and resources than anything. I've done some searching on here and online, and haven't found anything that really answers the question.
I was given an assignment to parse a string into tokens, implemented using the following prototype verbatim:
int makearg(char *s, char ***args);
I did so using something like the following:
int makearg(char *s, char ***args){
char temp[255];
int count = 0;
///////
//Count words in string
///////
*args = calloc( count , sizeof(char*));
//OR: *args = (char**) malloc(count * sizeof(char*));
count = 0;
while( //Not at end of s// ){
//Copy word into temp
if( //end of word// ){
*args[count]=calloc( strlen(temp), sizeof(char));
//OR: *args[count] = (char*) malloc(count * sizeof(char));
strcpy(*args[count],temp);
count++;
}
}
return count;
}
int main(){
char inp[255];
char **tokens = NULL;
int count;
printf("ENTER COMMAND: ");
fgets(inp,255,stdin);
count = makearg(inp,&tokens);
printf("Number of arguments:%d\nArguments:",count);
int i = 0;
for(i=0;i<count;i++)
printf("\n%s", tokens[i]);
printf("\n");
return 0;
}
If I gave something like "testcommand"
the program appeared to work, but if I gave an input with two or more words, such as "This is my test command"
, it would start segfaulting on the second calloc/malloc line. Poking around with GDB showed that *args[0]
returned as expected ("This"
), but *args[1]
was attempting to access a point in memory it shouldn't.
I got it working using the following:
int makearg(char *s, char ***args){
char temp[255];
int count = 0;
char** tempargs;
///////
//Count words in string
///////
tempargs = calloc( count , sizeof(char*));
count = 0;
while( //Not at end of s// ){
//Copy word into temp
if( //end of word// ){
tempargs[count]=calloc( strlen(temp), sizeof(char));
strcpy(tempargs[count],temp);
count++;
}
}
*args = tempargs;
return count;
}
My question is, what's the difference here? From my understanding, *args
should be the same as using tokens
, especially for the purposes of malloc
. The bit at the end with *args = tempargs
is just setting tokens
to point at the same chunk of memory as tempargs
. How is this different from pointing *args
at the malloc
memory in the first place?
My professor described the above solution as the way he usually does it, but didn't give a better explanation than "it strips off a layer of redirection in the body of the function". This makes sense, and is a convention I've seen elsewhere on here while trying to find answers, but doesn't help me understand. I asked around a bit in person, but the best answer I got was "eh. Scope/compiler shenanigans probably. It looks the same?".
Where should I go to find more on this?