【问题标题】:C++: "Error: Pointer being freed was not allocated" when handling large listsC++:处理大型列表时出现“错误:未分配指针”
【发布时间】:2014-03-24 12:06:49
【问题描述】:

我正在尝试处理由二维点组成的 std::vector 中的一些数据;基本上,我需要检查所有点是否直接或通过另一个点间接通过某种关系联系在一起,我认为这里不需要详细说明。

为了正确处理我的数据,我从向量中复制了数据并使用列表来加快处理速度。

我写了以下二维向量类:

class float2D {
public:
    float x, y;

    float2D(): x(0), y(0) {}
    float2D(int a, int b): x(a), y(b) {}

    bool CheckStuffWith(float2D &u); // does some math
};

用于处理数据的代码如下所示:

bool CheckStuffInVector(vector<float2D> const &data) { 
    if (data.size() < 2) return true;

    // Copy the data in a list, will be thinned out progressively
    list<float2D> data_copy(data.begin(), data.end());

    // Points used to CheckStuff with the remaining points in data_copy
    list<float2D> processed_data;

    // Choose arbitrarily the last element to compare with the others
    processed_data.push_back(data_copy.back());
    data_copy.pop_back();

    list<float2D>::iterator it1;
    list<float2D>::iterator it2 = data_copy.begin();

    while (!processed_data.empty()) {
        it1 = processed_data.begin();
        if (it1->CheckStuffWith(*it2)) {
            // *it2 fulfills the relationship
            // Remove the point from data_copy
            // and put it in processed_data
            processed_data.push_back(*it2);
            data_copy.erase(it2);
        } else {
            // Move on to the next point to process
            it2++;
        }
        if (it2 == data_copy.end() && !data_copy.empty()) {
            // We checked all the necessary stuff with *it1
            // No need to keep it in processed_data
            processed_data.pop_front();
            it2 = data_copy.begin();
        } else if (data_copy.empty()) {
            break;
        }
    }

    return data_copy.empty();
}

data.size() 的值相对较低时运行良好,但我需要它来处理更大的值。当向量的大小为 1,000,000 时,出现以下运行时错误:

malloc: *** error for object 0x7fac0e341240: pointer being freed was not allocated

我不知道这是从哪里来的。我可能忽略了一些东西,但我看不到它是什么;我认为局外人的看法可能会有所帮助:)

我还想指出,这样的问题可以使用树结构来处理,但是由于问题的大小,这可能会导致树的高度非常大(因此,堆栈溢出的风险?)和事实上,我想要一些运行得很快的东西,我想我最好这样做。

提前致谢!

【问题讨论】:

  • 两件事:您不需要为float2d 定义自己的复制构造函数/赋值运算符。并考虑(例如)如果data 只有一个元素会发生什么:data_copy 在你的循环开始之前将是空的,你基本上会尝试erase(data_copy.end())
  • @Roddy:感谢您的回答!如果data 只有一个元素,则该函数应返回true,无需额外计算,如第一行所述:if (data.size() &lt; 2) return true;

标签: c++ list vector malloc runtime-error


【解决方案1】:

当您执行data_copy.erase(it2) 时,会使迭代器it2 无效,然后在while 循环的下一次迭代中取消对迭代器的引用。这是UB。

我建议你用这个替换擦除线来解决这个问题

it2 = data_copy.erase(it2)

如果列表为空,它将用指向下一个元素的有效迭代器或 data_copy.end() 替换 it2 迭代器。

【讨论】:

  • 你是对的!我没有发现这一点,它可能会导致一些问题。谢谢!我现在要检查它是否工作正常(可惜程序现在运行速度超慢,由于某种原因,所以我必须等待很长时间......)。
  • 好的,这就是问题的根源。我的代码超级慢,但这就是原因。谢谢!
猜你喜欢
  • 1970-01-01
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
  • 2020-09-26
相关资源
最近更新 更多