【问题标题】:C++ Memory LeaksC++ 内存泄漏
【发布时间】:2017-02-18 08:34:38
【问题描述】:

我有 2 个文件,其中一个是我的测试类。我的代码编译并执行,但是我无法摆脱内存泄漏。我整天都在尝试,并且越来越近,但我被卡住了!我使用了 valgrind,它显示了内存泄漏,但我不确定如何修复它们。我的代码没有创建一个对象,所以我很困惑。请帮忙!

#ifndef A2_HPP
#define A2_HPP

#include <algorithm>

class sorted_sc_array {
public:

/*
 * return: none
 * constructor with no argument assign size_ = 0 and ptr_ to null pointer
 */
sorted_sc_array() : size_(0), ptr_(nullptr) {
}

/*
 * return: none
 * destructor delete the pointer ptr_
 */
~sorted_sc_array() {
    delete[] ptr_;
}

/*
 * return: none
 * when assign an object to new object
 */
sorted_sc_array(const sorted_sc_array& A){
    int sz = A.size_;
    this->size_ = 0;
    for(int i = 0; i < sz; i++) this->insert(A.data()[i]);
}

/*
 * return: sorted_sc_array
 * overloading of operator =
 */
sorted_sc_array& operator=(const sorted_sc_array& A){
    int sz = A.size_;
    this->size_ = 0;
    for(int i = 0; i < sz; i++) this->insert(A.data()[i]);;
}

/*
 * return int
 * return the size of the ptr_
 */
int size() const {
    return size_;
}

/*
 * return char*
 * return the deta stored in the pointer ptr_
 */
const signed char* data() const {
    return ptr_;
}

/*
 * return void
 * add new char to the pointer ptr_ and sort the the new string after      addition
 */
void insert(signed char c) {
    if(size_ == 0){
        ptr_ = (signed char*)malloc(2*sizeof(char));
        ptr_[0] = c;
        ptr_[1] = '\0';
    }else {
        ptr_ = (signed char*)realloc(ptr_, (size_ + 2)*sizeof(char));
        ptr_[size_] = c;
        ptr_[size_ + 1] = '\0';
    }
    size_++;
    std::sort(ptr_, ptr_ + size_);
}


private:
int size_; // size of the array
signed char* ptr_; // pointer to the array

}; // class sorted_sc_array

#endif // A2_HPP

这是测试其他类

/*
 * File: a2.pp
 * Description: testing class a2.hpp
 */

#include <iostream>
#include "a2.hpp"


int main(int argc, char* argv[]) {
sorted_sc_array A;

{
    sorted_sc_array T;
    for (signed char c = -128; c < 127; ++c) T.insert(c);

    T = T;

    sorted_sc_array V = T;
    A = V;
}

const auto first = A.data();
const auto last = first + A.size();

auto size = A.size();
bool res = std::is_sorted(first, last);

if (!res || (A.size() != 255)) std::cout << "fail";
else std::cout << "pass";

std::cout << std::endl;

return 0;
} // main

这就是我从 valgrind 得到的:

    ==8291== Memcheck, a memory error detector
==8291== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8291== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==8291== Command: ./a2
==8291== 
==8291== Mismatched free() / delete / delete []
==8291==    at 0x402ECB8: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==8291==    by 0x8048A39: main (in /home/jay/A2/a2)
==8291==  Address 0x4416480 is 0 bytes inside a block of size 256 alloc'd
==8291==    at 0x402F2CC: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==8291==    by 0x80488D6: main (in /home/jay/A2/a2)
==8291== 
==8291== Mismatched free() / delete / delete []
==8291==    at 0x402ECB8: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==8291==    by 0x8048A42: main (in /home/jay/A2/a2)
==8291==  Address 0x440b0b8 is 0 bytes inside a block of size 256 alloc'd
==8291==    at 0x402F2CC: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==8291==    by 0x8048822: main (in /home/jay/A2/a2)
==8291== 
pass
==8291== Mismatched free() / delete / delete []
==8291==    at 0x402ECB8: operator delete[](void*) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==8291==    by 0x8048AAF: main (in /home/jay/A2/a2)
==8291==  Address 0x4421848 is 0 bytes inside a block of size 256 alloc'd
==8291==    at 0x402F2CC: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==8291==    by 0x804899A: main (in /home/jay/A2/a2)
==8291== 
==8291== 
==8291== HEAP SUMMARY:
==8291==     in use at exit: 19,200 bytes in 2 blocks
==8291==   total heap usage: 1,022 allocs, 1,020 frees, 151,548 bytes allocated
==8291== 
==8291== 256 bytes in 1 blocks are definitely lost in loss record 1 of 2
==8291==    at 0x402F2CC: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==8291==    by 0x804874C: main (in /home/jay/A2/a2)
==8291== 
==8291== LEAK SUMMARY:
==8291==    definitely lost: 256 bytes in 1 blocks
==8291==    indirectly lost: 0 bytes in 0 blocks
==8291==      possibly lost: 0 bytes in 0 blocks
==8291==    still reachable: 18,944 bytes in 1 blocks
==8291==         suppressed: 0 bytes in 0 blocks
==8291== Reachable blocks (those to which a pointer was found) are not shown.
==8291== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==8291== 
==8291== For counts of detected and suppressed errors, rerun with: -v
==8291== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)

【问题讨论】:

  • 首先,简单地使用std::string 和/或std::vector 而不用这种编码风格折磨自己有什么问题?其次,你的类有一个完全混乱的赋值运算符,因为它会泄漏内存。
  • 我相信即使是一个空的 main() 程序也会泄漏一个 256 字节的块。试试看。
  • sorted_sc_array&amp; operator 覆盖应该return *this;

标签: c++ debugging data-structures memory-leaks valgrind


【解决方案1】:

您的 operator=size_ 设置为 0。

size_ 为0 时,你的insert() 分配一个新数组,并将ptr_ 设置为它,泄漏_ptr 中先前分配的数组。

您的赋值运算符还需要显式地delete_ptr,然后将其设置为nullptr,然后再启动复制。

您仍在使用delete 处理malloc-ed 数组。这是未定义的行为,也是另一个错误。

【讨论】:

  • 那么我该如何解决? :(
  • 重读我的回答的最后两段,它告诉你所有你需要知道的,为了解决它。
【解决方案2】:

您使用malloc/realloc 分配内存,但使用delete[] 释放它。您需要调用free 来释放内存。

【讨论】:

    猜你喜欢
    • 2016-01-27
    • 2010-11-11
    • 1970-01-01
    • 2015-11-19
    • 2014-11-01
    • 2020-03-31
    • 2016-03-15
    • 2015-07-25
    • 2018-01-03
    相关资源
    最近更新 更多