سؤال

The execv function takes an array of pointers as a second parameter. I have a pointer to a pointer, a dynamically created string list.

How do I create an array of pointers from this?

char **list = malloc((argc)*sizeof(char*));
int i=0;
for(i=0;i<argc;++i){ // using argv for example...
 list[i] = malloc(strlen(argv[i])+1);
 strcpy(list[i], argv[i]);
}
// create from list an array of pointers
execv(list_pointers[0], list_pointers);

Otherwise I get a Bad address error if passing in simply list to execv.

هل كانت مفيدة؟

المحلول

The signature of the function execv declared in the header unistd.h is

int execv(const char *path, char *const argv[]);

Please note that this is the same as

int execv(const char *path, char *const *argv);

which means that argv is a pointer to an object of type char * const, i.e., a constant pointer to a character. Also, the man page of execv says -

The first argument, by convention, should point to the filename associated with the file being executed. The array of pointers must be terminated by a NULL pointer.

Also, list, whose type is char **, is assignment compatible with the second argument of execv. I suggest the following changes -

// +1 for the terminating NULL pointer required for the 
// second argument of execv

char **list = malloc((argc + 1) * sizeof *list); 
if(list == NULL) {
    printf("not enough memory to allocate\n");
    // handle it
}
int i = 0;
for(i = 0; i < argc; ++i) {
    // strdup returns a pointer to a new string
    // which is a duplicate of the string argv[i]
    // this does effectively the same as the commented 
    // out block after the below statement.
    // include the header string.h for the prototype
    // of strdup POSIX function.

    list[i] = strdup(argv[i]);

    /* 
    list[i] = malloc(strlen(argv[i])+1);
    if(list[i] == NULL) {
        printf("not enough memory to allocate\n");
        // handle it
    }
    strcpy(list[i], argv[i]);
    */
}

list[argc] = NULL;  // terminate the array with the NULL pointer
execv(list[0], list);

نصائح أخرى

From execv man page:

"The array of pointers must be terminated by a NULL pointer."

The function execv doesn't know the argument count

 char **list = malloc((argc+1)*sizeof(char*));
 if (list == NULL) {
     abort();
 }
 int i;
 for(i=0;i<argc;++i){ // using argv for example...
     if ((list[i] = strdup(argv[i])) == NULL) {
         abort();
     }
 }
 list[argc] = NULL;
 execv(list[0], list);

EDIT I also removed list+1 from the execv call, thanks for @ajay for finding it

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top