为什么重载算术运算符 minus 与 valgrind 冲突?

问题描述 投票:0回答:1

在为十进制数类实现运算符重载时,我遇到了一个问题。我使该运算符保持不变,因为没有任何参数发生变化。但是Valgrind给出了以下问题,据我了解,该问题与disruptor有关。

void Seven::resizeArrayMinus()
{
    unsigned char* tmp = new unsigned char[_size - 1];
    std::memcpy(tmp, _array, (_size - 1) * sizeof(unsigned char));

    delete this->_array;
    _array = tmp;
    _size--;
}

valgrind 怎么说:

==10049== Mismatched free() / delete / delete []
==10049==    at 0x484BB6F: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==10049==    by 0x109CE4: Seven::resizeArrayMinus() (in /mnt/c/oop_lab/lab2/lab2)
==10049==    by 0x10A4CE: Seven::operator-(Seven const&) const (in /mnt/c/oop_lab/lab2/lab2)
==10049==    by 0x10A3A3: Seven::operator-(Seven const&) const (in /mnt/c/oop_lab/lab2/lab2)
==10049==    by 0x109471: main (in /mnt/c/oop_lab/lab2/lab2)
==10049==  Address 0x4dd6160 is 0 bytes inside a block of size 4 alloc'd
==10049==    at 0x484A2F3: operator new[](unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==10049==    by 0x10965F: Seven::Seven(unsigned long const&, unsigned char) (in /mnt/c/oop_lab/lab2/lab2)
==10049==    by 0x10A3F8: Seven::operator-(Seven const&) const (in /mnt/c/oop_lab/lab2/lab2)
==10049==    by 0x10A3A3: Seven::operator-(Seven const&) const (in /mnt/c/oop_lab/lab2/lab2)
==10049==    by 0x109471: main (in /mnt/c/oop_lab/lab2/lab2)
==10049==

如果从运算符中删除常量值,问题就消失了

c++ constants operator-overloading valgrind
1个回答
0
投票

Valgrind 告诉你出了什么问题。

==10049== Mismatched free() / delete / delete []

规则非常简单。

  1. 如果您使用
    malloc
    calloc
    realloc
    进行分配,则使用
    free
  2. 取消分配
  3. 如果使用
    new
    分配,则使用
    delete
  4. 取消分配
  5. 如果使用
    new[]
    分配,则使用
    delete[]
    取消分配。

我想说还有第零条规则。

  1. 不要使用原始指针。请参阅 C++ 核心指南中的这些two items。使用标准库容器。你的数组确实应该是一个
    std::vector
    。如果你不能使用容器,那就使用智能指针。

还有对齐分配/解除分配和大小解除分配的规则。我添加了对违反这些规则的检查,这将在即将到来的 Valgrind 3.22 中进行,但这与这里无关。

回到你的错误,Valgrind 告诉你你在哪里进行了释放

==10049==    at 0x484BB6F: operator delete(void*, unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==10049==    by 0x109CE4: Seven::resizeArrayMinus() (in /mnt/c/oop_lab/lab2/lab2)

(Valgrind 已用自己的版本替换了 C++ 库分配器,这就是为什么第一行引用 vgpreload_memcheck-amd64-linux.so 而不是 libstdc++.so 或 libc++.so)。

那是

delete

它还告诉你它在哪里看到了该内存块的分配

==10049==    at 0x484A2F3: operator new[](unsigned long) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==10049==    by 0x10965F: Seven::Seven(unsigned long const&, unsigned char) (in /mnt/c/oop_lab/lab2/lab2)

那是

new[]

所以你正在做一个“数组新”但是一个“非数组删除”。

严格来说,这是未定义的行为。这很糟糕。实际上,如果您分配的类型没有任何类型的析构函数,您可能会遇到这种错误。不能保证这一点,所以你真的应该修复你的代码。

最后一件事,我猜你的应用程序对性能并不关键,但是每次数组大小减少一个时取消分配和重新分配数组会非常慢。只有当系统内存真的紧张时,我才会考虑这样做。

© www.soinside.com 2019 - 2024. All rights reserved.