我有一个问题,我需要一个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的值传入向量。有什么想法吗?非常感谢帮助。谢谢!
答案 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 *
字符串时出现了什么问题。