darksky
darksky

Reputation: 21049

Copying Double Pointer Strings

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 mallocing 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

Answers (2)

sirgeorge
sirgeorge

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

JaredPar
JaredPar

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

Related Questions