【问题标题】:std::make_unique<bool[]>(x) is giving me malloc(): invalid size (unsorted) errorstd::make_unique<bool[]>(x) 给我 malloc(): invalid size (unsorted) 错误
【发布时间】:2021-11-07 08:59:37
【问题描述】:
  1. 我正在尝试创建一个 Bool Array 类,该类接受一串整数并将它们转换为 bool 数组。一旦我有 2 个布尔数组变量,我就会执行 Karatsuba 乘法。

以下是实际错误的来源。

explicit BoolArray(BoolArray const &ref, int start) : dimensions_{ref.dimensions_-1} {
                //std::cout << ref << std::endl;
                //std::cout << "Start" << std::endl;
                //std::cout << ref.dimensions_-1 << std::endl;
                //std::cout << dimensions_ << std::endl;
                //std::cout << start << std::endl;
                sign_ = false;
                //std::cout << "Make_unique" << std::endl;
                arr_ = std::make_unique<bool[]>(dimensions_); //Line doesn't run in some cases
                //std::cout << "Make_unique Accomplished" << std::endl;
                std::memcpy(arr_.get(),ref.arr_.get()+start,dimensions_*sizeof(bool));
                //std::cout << *this << std::endl;
            }

这些是我的私有变量。

mutable unsigned int dimensions_;
mutable std::unique_ptr<bool[]> arr_;

我使用 GDB 找出错误发生的位置,它指向了这个特定的函数调用。然后我使用 print 语句来确定没有运行的确切行是 make_unique 行。

现在有趣的是,假设我要将 5000 位数字乘以 5000 位数字。它首先转换为 bool 数组。然后相乘,乘法完美,并返回另一个 bool 数组。

然而,在 13000 位的情况下,将它们相乘时,我特别得到错误:malloc(): invalid size (unsorted) 错误。

现在,我不希望有人对此进行调试,但我正在寻找 std::make_unique(x), 可能中断的原因?

谢谢

编辑: 我刚刚使用了 valgrind,我似乎得到了很多 ==14286== 大小为 1 的读取无效 ==14286== 大小为 1 的无效写入 ,但到目前为止我得到的输出一直很好。我什至尝试将其用于 1 和 1 之间的简单乘法。而且我在使用 valgrind 时遇到了很多错误,但我认为它只是运行顺利。 编辑:

我认为到目前为止导致错误的原因是这个特定的功能。 请注意,else 语句基本上是重复使用的代码(我知道我也可以不使用 if 语句),但是使用下面的代码我得到了 valgrind 错误,我将在下面复制粘贴。

 friend BoolArray operator+(BoolArray &x, BoolArray  &y) {
                if (x.size() <= y.size()) {
                    int max = y.size();
                    int min = x.size();
                    int mSize = max;
                    auto ret = BoolArray(++mSize);
                    bool remainder = 0;

                    for (; min >= 0; --min) {
                        ret[mSize] = output_[remainder][ y[max] ][x[min] ];
                        remainder = carry_[remainder][ y[max] ][ x[min] ];
                        --max;
                        --mSize;
                    }
                    
                    for (; max >= 0; --max) {
                        ret[mSize] = output_[remainder][ y[max] ][ 0 ];
                        remainder = carry_[remainder][ y[max] ][ 0 ];
                        --mSize;
                    }

                    if (remainder) {
                        ret[mSize] = 1;
                    } else {
                        auto newRet = BoolArray(ret,1);
                        return newRet;
                    }
                    return ret;

Valgrind 错误

==14457== Invalid read of size 1
==14457==    at 0x10BABA: BigNum::operator+(BigNum::BoolArray&, BigNum::BoolArray&) (DataStructure.cpp:422)
==14457==    by 0x10A65A: main (DataStructure.cpp:693)
==14457==  Address 0x4da8f52 is 0 bytes after a block of size 2 alloc'd
==14457==    at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==14457==    by 0x10C26F: std::_MakeUniq<bool []>::__array std::make_unique<bool []>(unsigned long) (unique_ptr.h:863)
==14457==    by 0x10AB46: BigNum::BoolArray::BoolArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (DataStructure.cpp:58)
==14457==    by 0x10A5CD: main (DataStructure.cpp:688)
==14457==
==14457== Invalid read of size 1
==14457==    at 0x10BAD9: BigNum::operator+(BigNum::BoolArray&, BigNum::BoolArray&) (DataStructure.cpp:422)
==14457==    by 0x10A65A: main (DataStructure.cpp:693)
==14457==  Address 0x4da8dc2 is 0 bytes after a block of size 2 alloc'd
==14457==    at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==14457==    by 0x10C26F: std::_MakeUniq<bool []>::__array std::make_unique<bool []>(unsigned long) (unique_ptr.h:863)
==14457==    by 0x10AB46: BigNum::BoolArray::BoolArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (DataStructure.cpp:58)
==14457==    by 0x10A57F: main (DataStructure.cpp:687)
==14457==
==14457== Invalid write of size 1
==14457==    at 0x10BB19: BigNum::operator+(BigNum::BoolArray&, BigNum::BoolArray&) (DataStructure.cpp:422)
==14457==    by 0x10A65A: main (DataStructure.cpp:693)
==14457==  Address 0x4da93e3 is 0 bytes after a block of size 3 alloc'd
==14457==    at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==14457==    by 0x10C26F: std::_MakeUniq<bool []>::__array std::make_unique<bool []>(unsigned long) (unique_ptr.h:863)
==14457==    by 0x10ADAF: BigNum::BoolArray::BoolArray(unsigned int const&) (DataStructure.cpp:72)
==14457==    by 0x10BA8A: BigNum::operator+(BigNum::BoolArray&, BigNum::BoolArray&) (DataStructure.cpp:418)
==14457==    by 0x10A65A: main (DataStructure.cpp:693)
==14457==
==14457== Invalid read of size 1
==14457==    at 0x10BB3C: BigNum::operator+(BigNum::BoolArray&, BigNum::BoolArray&) (DataStructure.cpp:423)
==14457==    by 0x10A65A: main (DataStructure.cpp:693)
==14457==  Address 0x4da8f52 is 0 bytes after a block of size 2 alloc'd
==14457==    at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==14457==    by 0x10C26F: std::_MakeUniq<bool []>::__array std::make_unique<bool []>(unsigned long) (unique_ptr.h:863)
==14457==    by 0x10AB46: BigNum::BoolArray::BoolArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (DataStructure.cpp:58)
==14457==    by 0x10A5CD: main (DataStructure.cpp:688)
==14457==
==14457== Invalid read of size 1
==14457==    at 0x10BB5B: BigNum::operator+(BigNum::BoolArray&, BigNum::BoolArray&) (DataStructure.cpp:423)
==14457==    by 0x10A65A: main (DataStructure.cpp:693)
==14457==  Address 0x4da8dc2 is 0 bytes after a block of size 2 alloc'd
==14457==    at 0x483C583: operator new[](unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==14457==    by 0x10C26F: std::_MakeUniq<bool []>::__array std::make_unique<bool []>(unsigned long) (unique_ptr.h:863)
==14457==    by 0x10AB46: BigNum::BoolArray::BoolArray(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (DataStructure.cpp:58)
==14457==    by 0x10A57F: main (DataStructure.cpp:687)
==14457==
10 <- This is my output.

我正在运行的代码调用 + 重载

    auto m1 = BigNum::BoolArray("1"); //[01]
    auto m2 = BigNum::BoolArray("1"); //[01]

    std::cout << m1.size() << std::endl;
    std::cout << m2.size() << std::endl;

    std::cout << m1 + m2 << std::endl; //[10]

所以,现在我想我需要弄清楚为什么 + 重载会给我这些特定的错误..

【问题讨论】:

  • 考虑组合一个minimal reproducible example。您可能在其他地方出现内存损坏,导致此分配失败。找出触发它的事件序列,然后从那里向后工作以找到实际源。
  • 也许您的memcpy 读数超出范围。似乎start &gt; 1 可能会发生这种情况
  • make_unique() 失败时,dimensions_ 有什么价值?因为-1dimensions_被初始化时,如果ref.dimensions_为0,你会得到一个非常大的值。就个人而言,我会完全摆脱dimensions_,将arr_改为std::vector&lt;bool&gt;
  • 您可以使用std::bitset 来达到您的目的吗?还是std::vector&lt;bool&gt;
  • @Steveit 我知道std::make_unique&lt;bool[]&gt;(1671) 失败的唯一方法是您的内存不足,或者事先已经损坏了内存。

标签: c++ unique-ptr karatsuba


【解决方案1】:

我已经编辑了我的代码,所以事实证明 Remy 是对的,我事先通过访问我不应该成为的东西破坏了内存,因为我的 [] 运算符重载写得不好,所以我没有意识到我要去出界。所以我不得不在我的 + 运算符重载中调整代码。 int max = y.size();

                    int mSize = max+1;
                    max--;
                    int min = x.size();
                    min--;
                    auto ret = BoolArray(mSize);
                    mSize--;
                    bool remainder = 0;

对于这样的事情,我知道它非常难看,但可以完成工作。任何人都谢谢你,但同时我想知道这会特别影响 make_unique 函数发生的事情。

【讨论】:

    猜你喜欢
    • 2020-09-24
    • 1970-01-01
    • 2014-07-04
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多