无法将项添加到const char * vector中吗? C ++

时间:2018-03-02 23:51:18

标签: c++ string vector char c-strings

我有一个问题,我需要一个const char *的向量,但出于某种原因,每当我尝试添加一些东西时,没有任何事情发生。以下是相关的代码示例。

std::vector<const char*> getArgsFromFile(char* arg) {
    std::ifstream argsFile(arg);
    std::vector<const char*> args;
    while (!argsFile.eof()) {
        std::string temp;
        argsFile >> temp;
        args.push_back(temp.c_str());
    }
    args.pop_back();
    return args;
}

奇怪的是,如果我做出这个改变

std::vector<const char*> getArgsFromFile(char* arg) {
    std::ifstream argsFile(arg);
    std::vector<const char*> args;
    while (!argsFile.eof()) {
        std::string temp;
        argsFile >> temp;
        const char* x = "x";
        args.push_back(x);
    }
    args.pop_back();
    return args;
}

它会添加&#39; x&#39;到向量但我无法将temp的值传入向量。有什么想法吗?非常感谢帮助。谢谢!

2 个答案:

答案 0 :(得分:1)

const char* 不是一个字符串,但只是一个指向某个内存的指针,通常包含一些字符。现在std::string下面有一个小的内存区域(如char buff[32]),或者对于较大的字符串,它保存一个指向堆上分配的内存的指针。在任何一种情况下,都可以通过string::c_str()获得指向保存数据的实际存储器的指针。但是当string超出范围时,指针不再指向安全数据并变得悬空。

这就是为什么C ++引入了避免直接暴露和使用原始指针的方法的原因。好的C ++代码避免像瘟疫这样的原始指针。你的作业是针对糟糕/糟糕的C ++代码(希望只是为了解这些原始指针带来的问题)。

因此,为了使vector中的指针持久指向某些字符(而不是变成悬空),它们必须指向持久性内存。实现这一目标的唯一保证方法是动态分配内存

while (!argsFile.eof()) {
    std::string temp;
    argsFile >> temp;
    char* buff = new char[temp.size()+1];          // allocate memory
    std::strncpy(buff,temp.c_str(),temp.size()+1); // copy data to memory
    args.push_back(buff);                          // store pointer in vector
}

但是以这种方式分配的内存将被泄露,除非你在

中解除分配
while(!args.empty()) {
    delete[] args.back();
    args.pop_back();
}

请注意,这是非常糟糕的C ++代码非异常安全(如果在分配和取消分配之间发生异常,则分配的内存泄露)。在C ++中,可以使用std::vector<std::string>std::vector<std::unique_ptr<const char[]>(如果你不能使用std::string),这两者都是异常安全的。

答案 1 :(得分:1)

使用基于标准库的实现

SL.1的指南C++ coding guidelines说:&#34;尽可能使用标准库&#34; (和相关的)。为什么这么努力?人们已经为你完成了大部分的工作......

因此,使用您的函数声明,您可以拥有:

std::vector<std::string> getArgsFromFile(char* arg) {
    using namespace std;
    ifstream argsFile(arg);
    vector<string> args;
    copy(istream_iterator<string>(argsFile),
          istream_iterator<string>(),
          back_inserter(args));
    return args;
}

鲍勃是你的叔叔。

尽管如此,@ Walter的answer阅读非常有用,这样您就会发现使用char *字符串时出现了什么问题。