【发布时间】:2020-09-13 03:27:43
【问题描述】:
我编写了一个名为 DSString 的自定义字符串类,其中包含一个私有成员 char* 数据。我正在尝试解析 csv 文件中的行,将文件行中找到的每个单词添加到 DSString 对象的 std::set 中。我调用 getline 将文件中的一行读入 char* 缓冲区,然后调用 strtok 来获取单词。但是,下面的 while 循环不起作用;我的调试器告诉我,在到达那行代码时,它会在 DSString.h 中使用参数 NULL 调用我的构造函数,然后程序结束。
int main (int argc, char ** argv) {
ifstream input;
input.open(argv1);
int reviewLinesCtr = 0;
char line[16000];
set <DSString>positiveWordSet;
while (input.getline(line,16000)) {
if (reviewLinesCtr == 10) break;
//Push review to positive set
DSString word = strtok(line, " ");
while (word != nullptr) { //Program ends abruptly here
positiveWordSet.insert(word);
word = strtok(nullptr, " ");
}
}
reviewLinesCtr++;
}
return 0;
}
DSString 只有私有成员 char *data 和 int size。
这是DSString中的相关代码:
DSString::DSString(const char* param) { //This is the constructor being passed, param = NULL, which crashes the program.
data = new char[strlen(param) + 1];
this->size = strlen(param) + 1;
strcpy(data, param);
}
DSString& DSString::operator= (const char* source) {
if (data != nullptr) {
delete[] data;
}
data = new char[strlen(source + 1)];
size = strlen(source) + 1;
strcpy(data, source);
return *this;
}
bool DSString::operator!= (const DSString& rhs) const {
if (strcmp(this->data, rhs.data) != 0) {
return true;
}
else {
return false;
}
}
这是大学项目的一部分,因此我们需要实现自定义 DSString 类。否则我不会使用它,而是使用 std::string。除了从文件中读取的缓冲区外,我们也不能在程序中的任何地方使用 char*。当我尝试开始执行此 while 循环时,为什么会调用此构造函数并将 NULL 作为参数?我该如何解决?
如果这是一个重复的问题,我深表歉意,我已经在互联网上搜索了一段时间,但没有找到任何有助于解释这里发生的事情的信息。 任何帮助将不胜感激。
【问题讨论】:
-
DSString word = strtok(line, " ");将调用Copy Initialization -
你有什么证据证明在以下行中:
word = strtok(nullptr, " ");,对strtok的调用永远不会返回NULL,因此将空指针传递给你的构造函数或operator=,结果在观察到的段错误中? (提示:你没有证据)。附:你的operator=有严重的内存泄漏。 -
strtok在 C++ 中很少使用,所以,尽量不要使用它。 -
您的赋值运算符泄漏内存。问题是您试图在应用程序中使用损坏的类,该类需要
DSString具有正确的复制语义,而DSString没有正确的复制语义。 -
set<DSString>-- 你真的需要发布你的整个DSString课程。假设这是std::set,就目前而言,这将惨遭失败,因为DSString类没有正确的复制语义,因此您的运行时错误可能源于代码中的多个错误。
标签: c++