尝试从指针向量中取消引用指针时出现分段错误

发布于 2024-12-07 20:50:20 字数 1616 浏览 0 评论 0原文

我有一个指向对象的指针向量,我正在使用 std::vector::iterator` 对其进行迭代。由于返回的元素本身就是一个指针,因此我取消引用迭代器两次,一次返回指针,一次将指针解析为实际对象。

我正在尝试调用返回 std::string 的成员函数 (getClass),并且我尝试了 (**it).getClass()(*it)->getClass() 但两者都给我一个分段错误。我总觉得我错过了一些明显的东西。

部分功能代码:

void dataSet::createFolds()
{
   // Shuffle the data vector
   std::random_shuffle( m_records.begin(), m_records.end());

   std::cout << "STARTING MAIN LOOP.  THERE ARE " << m_records.size() << " RECORDS\n";
   // iterate through the data vector and assign each to a fold
   std::vector<dataRecord *>::iterator it = m_records.begin();
   while (it != m_records.end())
   {
      std::string currentClass = (*it)->getClass();  // SEG FAULT HERE
      .
      .
      .
   }
   .
   .
   .
}

向量为m_records ... 代码

dataRecord 定义如下... code

回答有关填充向量的问题:

数据是从文本文件中读取的,我真的不想发布整个内容除非我必须(212 行),但填充向量的相关代码如下。 dataRecord 对象的构造函数采用字段对象向量。我使用临时指针,使用 new 创建对象,然后 Push_back 指针。

while ...
{
   std::vector<field> fields;

   // build the fields vector
   for (unsigned int i = 0; i < numAttribs; ++i)
      fields.push_back(field(data.at(i), attribTypes[i]));

   // create the new dataRecord
   dataRecord * newRecord = new dataRecord(fields);

   // add the record to the set
   m_records.push_back(newRecord);

   ++recordNum;
   std::cout << "read record " << recordNum << std::endl;
}

I have a vector of pointers to objects that I am iterating through using std::vector::iterator`. Since the element returned is itself a pointer I dereference the iterator twice, once to return the pointer and once to resolve the pointer to the actual object.

I'm trying to invoke a member function (getClass) that returns an std::string and I have tried both (**it).getClass() and (*it)->getClass() but both give me a segmentation fault. I keep feeling like I'm missing something obvious.

partial function code:

void dataSet::createFolds()
{
   // Shuffle the data vector
   std::random_shuffle( m_records.begin(), m_records.end());

   std::cout << "STARTING MAIN LOOP.  THERE ARE " << m_records.size() << " RECORDS\n";
   // iterate through the data vector and assign each to a fold
   std::vector<dataRecord *>::iterator it = m_records.begin();
   while (it != m_records.end())
   {
      std::string currentClass = (*it)->getClass();  // SEG FAULT HERE
      .
      .
      .
   }
   .
   .
   .
}

The vector is m_records ... code

dataRecord is defined like this ... code

In response to questions about filling the vector:

The data is read from a text file and I really don't want to post the entire thing unless I have to (212 lines) but the pertinent code for populating the vector is below. The constructor for the dataRecord object takes a vector of field objects. I use a temporary pointer, use new to create the object then push_back the pointer.

while ...
{
   std::vector<field> fields;

   // build the fields vector
   for (unsigned int i = 0; i < numAttribs; ++i)
      fields.push_back(field(data.at(i), attribTypes[i]));

   // create the new dataRecord
   dataRecord * newRecord = new dataRecord(fields);

   // add the record to the set
   m_records.push_back(newRecord);

   ++recordNum;
   std::cout << "read record " << recordNum << std::endl;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

熟人话多 2024-12-14 20:50:20

在我看来,向量元素的初始化很糟糕。也许您必须在测试提取向量之前独立测试填充向量的代码。对不起我的英语;)

In my opinion the vector elements are badly initialized. Perhaps you have to test the code that fill the vector independently before testing to extract them. Sorry for my english ;)

白鸥掠海 2024-12-14 20:50:20

容器中的指针要么为空,要么它们是指向已释放内存的悬空指针。

仔细检查填充 m_records 的代码。

Either the pointers in your containers are null, or they are dangling pointers to free'd memory.

Double check the code that fills m_records.

維他命╮ 2024-12-14 20:50:20

std::string dataRecord::getClass() {return m_data.at(m_data.size() - 1).getTextData();}

必须验证 m_data.size() 因为可能为 0,因此您将得到超出或范围的异常。

In

std::string dataRecord::getClass() {return m_data.at(m_data.size() - 1).getTextData();}

You must to verify m_data.size() because could be 0, so you will get an exception of out or range.

若沐 2024-12-14 20:50:20
// create the new dataRecord
   dataRecord * newRecord = new dataRecord(fields);

我猜这个错误是在 dataRecord 的构造函数中。你确定它正确地完成了它的工作吗?

// create the new dataRecord
   dataRecord * newRecord = new dataRecord(fields);

I'm guessing the bug is in dataRecord's constructor. Are you sure it's doing it's job properly?

七七 2024-12-14 20:50:20

这不一定适用于OP的问题,但对于那些通过谷歌搜索到达这里的人...

如果您在解除引用向量迭代器上收到段错误并且正在多线程应用程序中工作,请记住向量不一定是线程安全的!

如果没有互斥锁,以下示例是不安全的。

线程 1

myVector.push_back(new Object());

线程 2

std::vector<Object*>::iterator = myVector.begin();
for (it; it != myVector.end(); it++) {
    Object* obj = *it;
}

相反,应该执行类似的操作:

myMutex.lock();
myVector.push_back(new Object());
myMutex.unlock();

线程 2

myMutex.lock();
std::vector<Object*>::iterator = myVector.begin();
for (it; it != myVector.end(); it++) {
    Object* obj = *it;
}
myMutex.unlock();

This doesn't necessarily apply to the OP's question but for those arriving here from googling...

If you're receiving segfaults on dereferencing vector iterators and are working in multi-threaded applications, remember that vectors aren't necessary thread-safe!

The following example is unsafe without mutex locks.

Thread 1

myVector.push_back(new Object());

Thread 2

std::vector<Object*>::iterator = myVector.begin();
for (it; it != myVector.end(); it++) {
    Object* obj = *it;
}

Instead, something like this should be done:

myMutex.lock();
myVector.push_back(new Object());
myMutex.unlock();

Thread 2

myMutex.lock();
std::vector<Object*>::iterator = myVector.begin();
for (it; it != myVector.end(); it++) {
    Object* obj = *it;
}
myMutex.unlock();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文