Reputation:
So I saw this example:
int main()
{
char *ls[] = {"ls", NULL};
char *grep[] = {"grep", "pipe", NULL};
char *wc[] = {"wc", NULL};
char **cmd[] = {ls, grep, wc, NULL};
loop_pipe(cmd);
return (0);
}
And loop_pipe() is a function to manipulate the arguments for multiple pipes. But the variables on this code which are inserted into cmd are already defined. On my personal code I'm trying to do the opposite, create the variable, insert the arguments into the variable and then add it to cmd. But what isn't happening is the 'adding' need. For instance, the code look like this:
*(cmd[pipe_count]) = arg;
I guess there is something wrong ('cause it's not working) but isn't using an index to set the location of insertion sufficient to allocate a pointer of array inside my double pointer? If not can someone help me clear how to assign like this?
Edit1:
My code simplified is like this:
char* arg[100];
char** cmd[100] = {};
int pipe_count = 0;
int index = 0;
arg[pipe_count] = (char *) malloc(sizeof(char) * 100);
for (int k = 0; params_vector[k][0] != '\0'; k++) { // percorrer todos os parametros. exemplo: ls | less | sort
if (strcmp(params_vector[k], "|") != 0) {
arg[index] = params_vector[k];
index++;
} else {
arg[index] = '\0';
*(cmd) = arg;
pipe_count++;
arg[pipe_count] = (char *) malloc(sizeof(char) * TAM);
index = 0;
}
}
Upvotes: 0
Views: 1534
Reputation: 164809
You can think of char **cmd[]
as an array which contains char **
elements. So you can assign char **
elements to it.
cmd[i] = arg;
It's as simple as that. It's not much different from an array of integers.
// "foo" is a `const char[]`. So an array of them is a `const char *[]`
const char *ls[] = {"ls", NULL};
const char *grep[] = {"grep", "pipe", NULL};
const char *wc[] = {"wc", NULL};
// To store an array of `const char *[]` we need a `const char **[]`.
const char **cmd[10] = {NULL};
cmd[0] = ls;
cmd[1] = grep;
cmd[2] = wc;
In more detail...
For simplicity, the rest of this example will treat char *[]
and char **
the same. There's some subtle differences, but for our purposes they don't matter. We'll treat ls
, grep
, and wc
as char **
pointers and cmd
as char ***
.
char **cmd[10]
allocates space for 10 char **
pointers on the stack. char **
are the same size as any other pointers. We'll assume 64 bit integers or 8 bytes. 10 of them means it allocates 80 bytes. cmd
itself is a char ***
pointer. That only has meaning to the compiler for type checking purposes. Ultimately all cmd
contains is a 64 bit integer representing a location in memory.
Same with ls
, grep
, and wc
. They are of type char **
which is just a 64 bit integer representing a location in memory.
cmd[0] = ls
says to start at the address of cmd
, advance by the size of 0 char **
pointers (so 0), and then assign the char **
pointer contained in the ls
to that location. So if cmd
is at memory location 100, this writes to 100 through 107.
cmd[1] = grep
says to start at the address of cmd
, 100. Advance by the size of 1 char **
pointers, 8. Then assign the char **
pointer contained in grep
to that location. So 100 + 8 is 108. Then write 8 bytes to 108 through 115.
And cmd[2] = grep
writes the 64 bit number in grep
to memory location 100 + (2 * 8) or 116 through 123.
And so on. It works this way for any array of pointers. Or pointers to pointers. It's just a fancy array of integers.
Upvotes: 1