Утечки памяти C

#c #debugging #data-structures #memory-leaks #valgrind

#c #отладка #структуры данных #утечки памяти #valgrind

Вопрос:

У меня есть 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_arrayamp; 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_arrayamp; operator=(const sorted_sc_arrayamp; 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] = '';
    }else {
        ptr_ = (signed char*)realloc(ptr_, (size_   2)*sizeof(char));
        ptr_[size_] = c;
        ptr_[size_   1] = '';
    }
    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 and / or std::vector и не мучить себя этим стилем кодирования? Во-вторых, в вашем классе полностью испорчен оператор присваивания, поскольку он пропускает память.

2. Я считаю, что даже пустая программа main() приведет к утечке одного 256-байтового блока. Попробуйте и посмотрите.

3. sorted_sc_arrayamp; operator переопределение должно return *this;

Ответ №1:

Ваши operator= значения size_ равны 0.

Когда size_ равно 0, ваш insert() выделяет новый массив и устанавливает ptr_ его, пропуская ранее выделенный массив в _ptr .

Ваш оператор присваивания также должен явно delete указать _ptr , а затем установить его в nullptr , перед началом копирования.

И вы все еще используете delete готовые malloc массивы. Это неопределенное поведение и еще одна ошибка.

Комментарии:

1. Итак, как я могу исправить ?? 🙁

2. Перечитайте последние два абзаца моего ответа, в которых рассказывается все, что вам нужно знать, чтобы исправить это.

Ответ №2:

Вы выделяете память с malloc помощью / realloc , но используете delete[] для ее освобождения. Вместо этого вам нужно вызвать free , чтобы освободить память.