0

I am trying to understand the ideas of pointers and references in C++. I am stuck with the following, what would be the specific behaviour in this case? I have a class like this:

class MyClass{
public:
     MyClass(const QByteArray & raw){
        this->m_rawData =raw;
     }
private:
   QByteArray m_rawData;
}

Let's say I create the instance like this:

bool otherClass::someOtherMethod(){
    QByteArray data = QString("sometext").toUtf8();
    MyClass instance = new MyClass(data);
    return true;
}

I pass the data variable address to my class constructor, then I exit the local method of OtherClass. The QByteArray data will be destroyed and its memory freed, right? But what will happen in MyClass instance ? Will this

 MyClass(const QByteArray & raw){
            this->m_rawData =raw;
         }

actually copy the content of raw into m_rawData or will it copy the actual reference of the raw and m_rawData will become invalid when the otherClass::someOtherMethod returns?

  • So the QByteArray data will be destroyed and its memory freed right? -- No. Your new class now holds a reference to it. Even so, in C++, you're generally responsible for memory management unless you use a smart pointer (C++ is not a garbage-collected language), so if you fail to deallocate the memory, it will simply leak unless you maintain a reference to it. – Robert Harvey Jul 8 '16 at 15:20
  • @RobertHarvey so this operation here this->m_rawData =raw; will copy the address of raw into m_rawData ? I was thinking that it would do something like this: QByteArray& operator=(const QByteArray &other) { this->c_str = malloc(other.size()); this->c_str = strcpy(other.c_str); //etc .. return *this; } – Vlad Jul 8 '16 at 15:23
  • That's... not really what copying references does. – Robert Harvey Jul 8 '16 at 15:25
  • 2
    I think the variable will be actually copied, because you have a value, not a reference on the left side. – Andy Jul 8 '16 at 17:25
  • 1
    Yes, and then you have undefined behaviour when the passed element gets deleted after it leaves its scope. – Andy Jul 8 '16 at 17:36
5

Under the hood, it might be implemented differently, but the visible effect of

MyClass(const QByteArray & raw){
        this->m_rawData =raw;
}

will be that the contents of raw get copied into m_rawData and will survive after raw has been destructed.

This works because m_rawData is declared as being a value of type QByteArray. If it would have been a pointer or a reference, then it would have been left dangling if raw was destructed before m_rawData.

One important thing to remember in C++ is that everything is a value unless you explicitly make it a pointer or a reference.

  • Thanks i think thats the best answer it explains everything – Vlad Jul 19 '16 at 2:47
0

... copy the content of raw into m_rawData or it will copy the actual reference of the raw and m_rawData will become invalid when the otherClass::someOtherMethod returns?

this->m_rawData =raw;

will likely trigger the copy assignment operator on QByteArray. This is because you didn't initialize m_rawData in the initializer block and you therefore likely called the default constructor on QByteArray to initialize m_rawData. After that occurred, in the ctor, your assigning the contents of data to m_rawData via copy assignment.

The default copy assignment operator probably is:

QByteArray &operator=(const QByteArray& other) {
  return *this;
}

which assigns values in other to this. However, the compiler generated assignment operator likely just returns a this pointer likely leaving all the values in QByteArray as garbage where nothing actually gets copied. (This is a good reason to 'delete' all the compiler generated class method in practice)

To fix this you need a valid copy assignment operator on QByteArray.

Also this:

bool otherClass::someOtherMethod(){
    QByteArray data = QString("sometext").toUtf8();
    MyClass instance = new MyClass(data);  // leak!
    return true;
}  

Memory should be owned. If you insist on dynamic memory do this:

bool otherClass::someOtherMethod(){
    QByteArray data = QString("sometext").toUtf8();
    std::unique_ptr<MyClass> fixed(new MyClass(data));
    return true;
}

So the QByteArray data will be destroyed and its memory freed right?

Once the original stack variable 'data' goes out of scope it will trigger it's destructor.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.