0

I am learning C++ and I am running in a problem that I don't know the reason for. I have created a vector and matrix class that are light wrappers around a C array that manage a T* array on the heap.

The Matrix class has a function:

// in NBDMatrix.hpp class definition
void makeXMeshgridv1(NBDVector<T> v){ // takes a value
    for(unsigned int j=0; j<ny; j++){
        for(unsigned int i=0; i<nx; i++)
            this->at(i,j) = v.at(i);
    }
}

void makeXMeshgridv2(NBDVector<T>& v){ // takes a reference
    for(unsigned int j=0; j<ny; j++){
        for(unsigned int i=0; i<nx; i++)
            this->at(i,j) = v.at(i);
    }
}

in main()

NBDVector<float> vec1 = NBDVector<float>(0.0f, 12.6f, 4);
NBDVector<float> vec2 = NBDVector<float>(0.0f, 12.6f, 4);
NBDMatrix<float> mat1(4,8);
NBDMatrix<float> mat2(4,8);

mat1.makeXMeshgridv1(vec1); // causes problem at destruction
mat2.makeXMeshgridv2(vec2); // no problem at destruction

If I use makeXMeshgridv1() I get

 malloc: *** error for object 0x100604c50: pointer being freed was  not allocated at destruction

but when I use makeXMeshgridv2 everything goes well.

I would like to understand what is the problem when using makeXMeshgridv1().

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
simford
  • 25
  • 3
  • 2
    Maybe your `NBDVector` and `NBDMatrix` classes don't follow the rule of 3 /5/ 0; https://en.cppreference.com/w/cpp/language/rule_of_three – drescherjm Dec 22 '18 at 18:06
  • 3
    My crystal ball tells me the answer is because you've not read, the followed guidance from, this question [What is the Rule of Three?](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) – WhozCraig Dec 22 '18 at 18:07
  • Your vector size (3) is not the same with one of the matrix dimensions (4x8). What do you expect your program works? Please provide more codes to clarify the matrix definition. – tunglt Dec 22 '18 at 18:17
  • *I am learning C++ and I am running in a problem that I don't know the reason for* -- Before using any home-made class in a larger program, you need to ensure it has the correct copy semantics. In other words, creating copies of, assigning copies of, and destroying `NBDVector`'s and `NBDMatrix`s need to work correctly and flawlessly. Obviously one or both do not properly copy correctly, and you don't need a function call to show that the classes you created are flawed. Since you didn't post either of those classes, that's the reasonable conclusion as to why your program fails. – PaulMcKenzie Dec 22 '18 at 19:06

1 Answers1

1

The one passed by value is likely not being properly deleted when it leaves its scope.

As others have mentioned you need to follow the rule of 0/3/5. The rule of 5 is for optimization so, you can focus on the rule of 0 and 3 for now.

https://en.cppreference.com/w/cpp/language/rule_of_three This is the example at the page linked.

rule_of_three(const char* s = "")
    : rule_of_three(s, std::strlen(s) + 1)
    {}
    ~rule_of_three()
    {
        delete[] cstring;  // deallocate
    }
    rule_of_three(const rule_of_three& other) // copy constructor
    : rule_of_three(other.cstring)
    {}
    rule_of_three& operator=(rule_of_three other) // copy assignment
    {
        std::swap(cstring, other.cstring);
        return *this;
    }
Eddie C.
  • 155
  • 8
  • This is a guess, not an answer. It's an educated guess, but this question does not contain enough information to be conclusively answered – user4581301 Dec 22 '18 at 19:21
  • 1
    This is the right answer. I had not written a copy constructor in the vector class which caused the copy to point at the same array as the initial object, hence that array was deallocated twice by the destructor. Thank you for your help. – simford Dec 22 '18 at 19:39