0
  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<bool []>(x), 可能中断的原因?

谢谢

编辑:我刚刚使用了 valgrind,我似乎得到了很多 ==14286== Invalid read of size 1 ==14286== Invalid write of size 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]

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

4

1 回答 1

0

我已经编辑了我的代码,所以事实证明 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 函数发生的事情。

于 2021-09-11T11:44:48.107 回答