2016-10-09 9 views
1

私は2つのファイルを持ち、そのうちの1つはテストクラスです。私のコードはコンパイルして実行しますが、メモリリークを取り除くことはできません。私は一日中努力してきましたが、近づいてきましたが、私は立ち往生しています!私はvalgrindを使用してmemリークを表示しますが、私はそれらを修正する方法がわかりません。私のコードには単一オブジェクトが作成されていないため、混乱してしまいます。助けてください!C++メモリリーク

#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) 
+1

まず、 'std :: string'や' std :: vector'を使うだけで、このコーディングスタイルで自分自身を苦しめないのはどうですか?第2に、あなたのクラスは完全に混乱した代入演算子を持っています。 – PaulMcKenzie

+0

私は空のmain()プログラムでさえ1つの256バイトブロックをリークすると信じています。それを試してみてください。 – bmargulies

+0

'sorted_sc_array&operator' overrideは' return * this; 'を返すべきです –

答えて

0

あなたはmalloc/reallocでメモリを割り当てるが、delete[]を使用していますそれを解放する。メモリを解放するには、freeに電話する必要があります。

3

あなたoperator=セットsize_

0に size_が0である場合には、あなたの insert()は、新しい配列を割り当て、 _ptrで以前に割り当てられた配列を漏洩し、それに ptr_を設定します。

代入演算子も、delete_ptrを明示的に指定してから、コピーを開始する前にnullptrに設定する必要があります。

-ed配列にはまだdeleteが使用されています。これは未定義の動作で、別のバグです。

+0

どうすれば修正できますか? :( – Jay

+1

私の答えの最後の2つの段落を読んでください。これは、あなたが知る必要があるすべてを教えてくれます。 –