Reputation: 21049
Assume I have char **argv
, so that argv[0] = some string
and argv[1] = another string
etc...
I have another double pointer string array in a struct, call it s1->argv
also defined as char **argv
within the struct.
I am trying to copy argv
into s1->argv1
. I tried malloc
ing s1->argv
to something with a max value (so 7 strings, each string of max 100 chars) and using strcpy
but that obviously does not work. It only ends up copying argv[0]
. This is how I used it: strcpy(*s1->argv, *argv)
How can I preserve each index of the array too?
Upvotes: 1
Views: 10338
Reputation: 6541
The code below makes a copy of argc
and argv
arguments of main
into user defined structure. The copy is exactly the same as original arguments (argv
is terminated by NULL
as in main). This code does not handle any abnormal events (like malloc failures, signal interruption etc.).
You may want to avoid casting the result of malloc
(it is not required in C), there is a lot of debate whether this casting is a good or bad thing. The choice is yours. I value portability more, so I choose to cast, compile with all warnings enabled and eliminate all of them in the code (see the comments to this answer).
#include <string.h>
#include <stdlib.h>
struct my_struct
{
int argc;
char** argv;
};
int main(int argc,char** argv)
{
int i = 0;
size_t n = 0;
struct my_struct s;
memset(&s,0,sizeof(s));
s.argc = argc;
/* alloc one more element than 'argc' to terminate 's.argv' with NULL */
s.argv = (char**)malloc((argc + 1) * sizeof(char*));
/* terminate 's.argv' with NULL exactly as 'argv' in 'main' */
s.argv[argc] = NULL;
for(i = 0; i < argc; ++i)
{
n = strlen(argv[i]) + 1;
s.argv[i] = (char*)malloc(n);
strcpy(s.argv[i],argv[i]);
}
return 0;
}
Another option for copying the strings in argv
could be using strdup
function, then you could replace the three lines:
n = strlen(argv[i]) + 1;
s.argv[i] = (char*)malloc(n);
strcpy(s.argv[i],argv[i]);
with
s.argv[i] = strdup(argv[i]);
Upvotes: 0
Reputation: 755179
It sounds like you just want to copy the entire argv
into another char**
value. If so then do the following
char** copy_all(char** argv, int length) {
char** ppDest = malloc(sizeof(char**) * length);
if (!ppDest) {
return NULL;
}
int i = 0;
for (i < length; i++) {
char* pCurrent = argv[i];
size_t currentLength = strlen(pCurrent);
ppDest[i] = malloc(currentLength + 1);
if (!ppDest[i]) {
goto Error;
}
strcpy(ppDest[i], argv[i]);
}
return ppDest;
Error:
while (i > 0) {
free(ppDest[i - 1]);
i--;
}
free(ppDest);
return NULL;
}
Upvotes: 4