从读取到对象指针数组的文件中获取段错误?
Posted
技术标签:
【中文标题】从读取到对象指针数组的文件中获取段错误?【英文标题】:Getting a segfault from a file read to an array of object pointers? 【发布时间】:2015-04-29 02:26:17 【问题描述】:所以我声明了一个指针数组,看起来像
Items* _items[ARRSIZE];
基本上是为了将它们用作一组对象(一个用于肉类,一个用于农产品),这些对象在运行时动态决定。我在构造函数中调用了以下函数,我已将其确定为我在 main 函数之前不断进行段错误的原因。
void Inventory::loadRecs()
datafile.open(_filename);
int i = 0;
char c;
//create fileif it doesnt exist
if(datafile.fail())
datafile.clear();
datafile.close();
datafile.open(_filename, ios::out);
datafile.close();
else
//read from file
while(!datafile.eof())
if(_items[i] != nullptr)
delete _items[i];
c = datafile.get();
if(c == 'P')
_items[i] = new Produce;
if (c == 'M')
_items[i] = new Meat;
datafile.ignore();
_items[i]->load(datafile);
i++;
datafile.ignore(); //ignore endl
_noOfItems = i;
datafile.close();
我正在阅读的文本文件是相当直接的阅读类似
P,123,胡萝卜,0.66,[NEWLINE] 第一个字符标识它是什么类型的产品(肉类或农产品),其余的行用 load 函数读入。
我的 Inventory 类看起来像这样:
class Inventory
char _filename[256];
Item* _items[5];
std::fstream datafile;
int _noOfItems;
构造函数只是初始化所有内容并调用loadsRecs(这是我从中获取段错误的地方)
【问题讨论】:
Item::load()
长什么样子?
Don't use datafile.eof(), it could have something to do with your problem.
另外,最好使用 RAII,而不是显式调用 open
和 close
。
对成员变量使用前导下划线也是一种不好的做法,因为您可能会与 reserved identifiers 发生冲突。
有什么理由不能使用标准库容器吗?看到像char _filename[256]
这样的静态大小的数组几乎总是表明您的程序由于缺少边界检查而出现严重错误。 std::string
没有这些问题。
【参考方案1】:
我敢打赌,您没有初始化指针数组,因此您对 nullptr
的检查失败,并且您正在对垃圾指针调用 delete
,从而导致未定义的行为。
除非您有一个从代码中省略的构造函数,否则指针是 default initialized 会导致不确定的值。
由于在您显示的代码中,您使用的是new Produce;
和new Meat;
,我假设您已经编写了new Inventory;
或Inventory i;
。相反,如果您包含括号(或 C++11 中的大括号),例如 new Produce();
或 Inventory i;
,您将得到 value initialization,这将执行您的指针的 zero initialization。这将导致您看似期望的行为。
【讨论】:
不会物品 _items[5];初始化它们? 在 C++11 中,default initialization 的数组会默认初始化值。在这种情况下,您的值是指针 not 对象。因此,假设您的Inventory
对象已默认初始化,它们将被初始化为不确定的值。以上是关于从读取到对象指针数组的文件中获取段错误?的主要内容,如果未能解决你的问题,请参考以下文章