【问题标题】:I can't figure out why I'm getting a seg fault in my code我不知道为什么我的代码中出现了段错误
【发布时间】:2020-02-04 01:24:12
【问题描述】:

所以我有这个

void MovieGroup::add(Movie* m)
{
  cout << "Size = " << size << endl;
  if(size < MAX_COLLECTION){

    if(size == 0){
      collection[0] = m;
    }
    else{

      for(int i = 0; i<size; i++){

        if(collection[i]->getYear() >= m->getYear()){

          for(int j = size-1; j != i; j--){
            collection[j] = collection[j-1];
          }
          collection[i] = m;
          break;

        }

        else{
          collection[size] = m;
        }

      }
    }

  size++;

  }
}

每次我尝试运行它时,都会出现分段错误。这样做的目的是向该集合中添加一个电影对象,但按年份排序。我真的不确定我在哪里非法访问内存。对此的任何帮助将不胜感激。

附加信息:MAX_COLLECTION 设置为 64,我试图从数组的后面开始将每个对象移动 1

【问题讨论】:

  • 调试器在哪里说发生了分段错误?这可能会给你一个线索。 collection[size] = m 这行看起来很可疑。
  • Edit 包含minimal reproducible example 的问题:MovieGroup 类的部分定义,包括构造函数以及collectionsize 成员变量。

标签: c++ segmentation-fault


【解决方案1】:

collection[size] = m; 行放错了位置。它需要在循环之外。

另外,当你移动元素时,你会丢失一些元素,因为你不会全部移动它们,所以你最终会覆盖其中的一些。

此外,您应该在移动元素后使用return 而不是break,否则您必须跟踪循环是否进行了移动,以便循环之后的代码可以相应地执行。

试试这个:

void MovieGroup::add(Movie* m)
{
  cout << "Size = " << size << endl;
  if (size < MAX_COLLECTION) {
    for (int i = 0; i < size; ++i) {
      if (collection[i]->getYear() >= m->getYear()) {
        for (int j = size-1; j >= i; --j) {
          collection[j+1] = collection[j];
        }
        collection[i] = m;
        ++size;
        return;
      }
    }
    collection[size] = m;
    ++size;
  }
}

话虽如此,我会进一步调整函数,因此只有 1 个插入点和增量而不是 2 个点:

void MovieGroup::add(Movie* m)
{
  cout << "Size = " << size << endl;
  if (size < MAX_COLLECTION) {
    int index = size;
    for (int i = 0; i < size; ++i) {
      if (collection[i]->getYear() >= m->getYear()) {
        for (int j = size-1; j >= i; --j) {
          collection[j+1] = collection[j];
        }
        index = i;
        break;
      }
    }
    collection[index] = m;
    ++size;
  }
}

然后,我建议使用标准算法而不是手动操作:

#include <algorithm>
#include <iterator>

void MovieGroup::add(Movie* m)
{
  cout << "Size = " << size << endl;
  if (size < MAX_COLLECTION) {
    auto collection_end = std::next(collection, size);
    auto iter = std::find_if(collection, collection_end,
      [=](Movie *movie){ return movie->getYear() >= m->getYear(); }
    );
    if (iter != collection_end) {
      std::copy_backward(iter, collection_end, collection_end + 1);
    }
    *iter = m;
    ++size;
  }
}

最后,您可能需要考虑将collection 更改为std::vector 而不是固定长度的数组,然后您可以使用std::vector::insert() 而不必担心手动移动元素或跟踪@987654330 @:

#include <algorithm>

void MovieGroup::add(Movie* m)
{
  cout << "Size = " << size << endl;
  auto iter = std::find_if(collection.begin(), collection.end(),
    [=](Movie *movie){ return movie->getYear() >= m->getYear(); }
  );
  collection.insert(iter, m);
}

【讨论】:

  • 这太棒了!我要添加的唯一内容是返回之前的 size++。编辑:刚刚刷新了我的页面,看到你们已经说过了,哈哈
  • 所以我在返回之前添加了 size++,它给了我另一个段错误。但是如果我删除它,它可以工作,但不能正确跟踪大小。
  • 无论如何,您都必须增加size,无论您将m 插入移位插槽还是结束插槽
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-08
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
  • 1970-01-01
  • 2018-12-19
相关资源
最近更新 更多