Results 1 to 7 of 7

Thread: Using variable length C array with execvp function

  1. #1
    Join Date
    Apr 2007
    Beans
    116

    Question Using variable length C array with execvp function

    Im wanting to use execvp to run a command. The problem is that it requires a const pointer to an array which in all the examples I can find is allocated on the stack like this:

    Code:
    char *const args[]={"progname","arg1","arg2",0};
    However my program will not know until runtime how many arguments there will be hence I need to allocate an array on the heap but doing this means I cant declare the pointer early on and keep the pointer constant.

    I have the args stored in a c++ vector but because execvp requires a constant pointer I dont see any way of copying them into a suitable array.

    Hope that makes sense?

    Thanks in advance

  2. #2
    Join Date
    Nov 2005
    Location
    Sendai, Japan
    Beans
    11,296
    Distro
    Kubuntu

    Re: Using variable length C array with execvp function

    Are you doing C or C++, then?
    「明後日の夕方には帰ってるからね。」


  3. #3
    Join Date
    Apr 2009
    Location
    Germany
    Beans
    2,134
    Distro
    Ubuntu Development Release

    Re: Using variable length C array with execvp function

    that execvp declares its interface as char * const only means that it will not modify the values in the array.
    It does not mean you have to pass in something const.

    const is just an annotation, it has not representation in the binary/abi
    Last edited by MadCow108; June 20th, 2012 at 10:52 PM.

  4. #4
    Join Date
    Apr 2007
    Beans
    116

    Re: Using variable length C array with execvp function

    Quote Originally Posted by Bachstelze View Post
    Are you doing C or C++, then?
    C++ but I need to get the strings into a C array to use the exec functions.

  5. #5
    Join Date
    Apr 2007
    Beans
    116

    Re: Using variable length C array with execvp function

    Quote Originally Posted by MadCow108 View Post
    that execvp declares its interface as char * const only means that it will not modify the values in the array.
    It does not mean you have to pass in something const.

    const is just an annotation, it has not representation in the binary/abi
    ah right. thanks for that tip.

    what would I declare the array as then in order than I can copy a series of variable length strings from the vector into it.

    Ive tried:
    Code:
    char** args; 
    args = new char*[words.size()];
    But then when I try to copy the string out of the vector with
    Code:
    args[x]=(const char*)words[x].c_str();
    I get an error
    invalid conversion from ‘const char*’ to ‘char*

    words is a C++ vector of std::strings

  6. #6
    Join Date
    Feb 2009
    Beans
    1,469

    Re: Using variable length C array with execvp function

    Because args[x] is a pointer to char and you're trying to give it the value of a pointer to const char. If it worked, then you could write to memory that was supposed to be labeled readonly (which is what 'const' really means).

    If you want args[x] to be a pointer to const char so that the assignment works, then you need to declare args as a pointer to pointer to const char: `char const **args;`

    I'm a little puzzled as to why you would think this was necessary in the first place. Just take the cast out. (Casts are rarely necessary and often indicative of poor design.)

  7. #7
    Join Date
    Jun 2007
    Location
    Maryland, US
    Beans
    6,288
    Distro
    Kubuntu

    Re: Using variable length C array with execvp function

    Quote Originally Posted by bluedalmatian View Post
    what would I declare the array as then in order than I can copy a series of variable length strings from the vector into it.
    This works for me:
    Code:
    #include <string>
    #include <vector>
    #include <iostream>
    #include <unistd.h>
    #include <cstring>
    
    int main()
    {
        std::vector<std::string> args;
        args.push_back("ls");
        args.push_back("-l");
    
        const size_t array_size = args.size();
    
        char** arg_array = new char*[array_size + 1];  // extra space for terminating NULL
    
        for (size_t i = 0; i < array_size; ++i)
        {
            arg_array[i] = strdup(args[i].c_str());
        }
        arg_array[array_size] = 0;
    
        execvp(arg_array[0], arg_array);
    
        std::cout << "This statement is never reached." << std::endl;
    }

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •