简体   繁体   中英

C++ Memory Leaks

I have 2 files, one of which is my testing class. My code compiles and executes, however I cant not get rid of the memory leaks. I have been trying all day and been getting closer and closer, but I am stuck ! I used valgrind and it shows mem leaks, but I am not sure how to fix them. My code doesnt have a single object created so I am so confused. please help!

#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

This is the testing the other class

/*
 * 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

And this is what I get from 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)

Your operator= sets size_ to 0.

When size_ is 0, your insert() allocates a new array, and sets ptr_ to it, leaking the previously-allocated array in the _ptr .

Your assignment operator also needs to explicitly delete the _ptr , and then set it to nullptr , before initiating the copy.

And you are still using delete for malloc -ed arrays. This is undefined behavior, and another bug.

You're allocating memory with malloc / realloc , but using delete[] to free it. You need to call free to free the memory instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM