Jay
Jay

Reputation: 21

C++ Debugging Help Memory Leak

I am currently working on an assignment and I am struggling greatly with debugging my memory leak. My program runs and passes however, when I upload it for grading my code has a memory leak. If someone could point me in the right direction on how to fix it I would greatly appreciate!

I've tried everything I could think of!

#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){
    const signed char* str = A.data();
    int sz = A.size_;
    this->size_ = 0;
    for(int i = 0; i < sz; i++) this->insert(str[i]);
    delete[] str;
}

/*
 * return: sorted_sc_array
 * overloading of operator =
 */
sorted_sc_array& operator=(const sorted_sc_array& A){
    const signed char* str = A.data();
    int sz = A.size_;
    this->size_ = 0;
    for(int i = 0; i < sz; i++) this->insert(str[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 the addition
 */
void insert(signed char c) {
    signed char *str = (signed char*)malloc((size_ + 1)*sizeof(char));
    for(int i = 0; i < size_; i++) str[i] = ptr_[i];
    str[size_++] = c;
    ptr_ = (signed char*)malloc((size_)*sizeof(char));
    for(int i = 0; i < size_; i++) ptr_[i] = str[i];
    std::sort(ptr_, ptr_ + size_);
    delete[] str;
}


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

The code compiles and executes, with a "pass" however there is a memory leak somewhere ! :(

Upvotes: 0

Views: 117

Answers (1)

Sam Varshavchik
Sam Varshavchik

Reputation: 118352

There are multiple bugs in the shown code.

In the copy constructor:

delete[] str;

This deletes the other object's buffer. The other object's destructor will attempt to delete[] its own buffer again, when it gets destroyed. This will result in memory corruption, and undefined behavior.

The obvious memory leak is in your insert():

ptr_ = (signed char*)malloc((size_)*sizeof(char));

There are two simultaneous bugs here.

  1. Using malloc for a buffer that the destructor will eventually delete[]. Only new-ed objects can be delete[]d. Using delete for a malloc-ed content is undefined behavior.

  2. The previous contents of ptr_ are not explicitly deleted, thus leaking memory.

The insert(), overall, is doing unnecessary allocation. There's no need to allocate a buffer twice, there. Only one allocation is sufficient: allocate, copy over the content to the new buffer, delete the old ptr_, and set ptr_ to the newly-allocated buffer.

Upvotes: 1

Related Questions