将vector <string>转换为char **会导致分段错误

时间:2016-01-02 21:13:28

标签: c++ segmentation-fault

我是C ++中的绝对优势,但我有一个助手。我必须将向量转换为char **才能在execvp中使用它。所以我写了这个测试正在构建好但是当我运行它我得到分段错误而不是&#34; First&#34;。我很擅长指针,我希望得到你的帮助。感谢

#include <iostream>
#include <vector>
#include <string>
#include <cstring>

using namespace std;

int main()
{
    vector<string>* list = new vector<string>();
    list->push_back("First");
    list->push_back("Second");
    list->push_back("Third");

    char ** arr;
    arr[0] = strdup(list->at(0).c_str());

    cout << arr[0] << endl;
    return 0;
}

编辑1

好的,这是实际问题。 Command :: getCommandArray()似乎按预期工作,但当我从main调用它并尝试显示arr [0]时,它再次导致分段错误。为什么呢?

// Command.cpp
char** Command::getCommandArray()
{
    int i=0;
    int len = args->size() + 2;
    char* arr[len];

    arr[0] = strdup(this->commandName->c_str());
    arr[len-1] = NULL;

    for (i=0; i<this->args->size(); i++)
    {
        arr[i+1] = strdup(this->args->at(i).c_str());
    }

    cout << "in: " << arr[0] << endl; // PRINTS AS EXPECTED

    return arr;
}

// main.cpp
do {
    char** arr = tmp->getCommandArray();
    cout << arr[0] << endl; // SEGMENTATION FAULT HERE
} while((tmp = tmp->getPipeline()) != NULL);

编辑2好的我解决了。非常感谢你!

我不得不换线

char* arr[len];

char** arr = new char*[len];

3 个答案:

答案 0 :(得分:3)

我认为没有理由在这里复制字符串,或者手动管理内存。您可以使用另一个向量来存储char指针,并获得指向该向量的内存的指针。

int main()
{
    std::vector<std::string> list;
    list.push_back("First");
    list.push_back("Second");
    list.push_back("Third");

    std::vector<char*> ptr_list;
    for (std::size_t i = 0; i != list.size(); ++i) {
        ptr_list.push_back(&list.at(i)[0]);
    }

    char** arr = &ptr_list[0];

    std::cout << arr[0] << std::endl;
}

答案 1 :(得分:2)

应该是这样的:

int main()
{
    std::vector<std::string> list;
    list.push_back("First");
    list.push_back("Second");
    list.push_back("Third");

    char** arr = new char*[list.size()];
    for (std::size_t i = 0; i != list.size(); ++i) {
        arr[i] = strdup(list.at(i).c_str());
    }
    std::cout << arr[0] << std::endl;

    for (std::size_t i = 0; i != list.size(); ++i) {
        free(arr[i]);
    }
    delete[] arr;
}

答案 2 :(得分:1)

请注意,传递给execve()的argv和envp数组需要以null结尾(除了这些数组中的字符串):

char ** convert(std::vector<std::string> v)
{
    char ** t = new char* [v.size() + 1];

    // Need this for execve
    t[v.size()] = nullptr;

    for (int i = 0 ; i < v.size(); ++i)
    {
        t[i] = strdup(v[i].c_str());
    }

    return t;
}
相关问题