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

问题描述 投票:0回答:2

我有一个问题,我需要一个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;
}

它会向向量添加'x'但我无法将temp的值加到向量中。有什么想法吗?非常感谢帮助。谢谢!

c++ string vector char c-strings
2个回答
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
投票

Use a standard-library-based implementation

SL.1的准则C++ coding guidelines说:“尽可能使用标准库”(及相关)。为什么这么努力?人们已经为你完成了大部分的工作......

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

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 *字符串时出了什么问题。

© www.soinside.com 2019 - 2024. All rights reserved.