Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No memory loss inside a class

Tags:

c++

I've got this code:

class MyClass{
public:
    string myString;
    MyClass(char *aString){
        this->myString = std::string(aString);
    }
}

int main(){
    MyClass example = MyClass("Hi!");
    printf("%s\n", example.myString.c_str());
    return 0;
}

Testing this with valgrind shows no problems, but I can't understand why I can avoid using new to create the string copy.

After the constructor execution ends shouldn't "this.myString" be lost in the stack?

Shouldn't I ask for that memory? Why?

Edit: I believe I'm getting confused because doing what I would consider "equivalent" in C, would cause errors when tested with valgrind:

typedef struct MyStruct{
    char *p;
}MyStruct_t;

void createMyStruct(MyStruct_t *aStruct, char *text){
    char str[10];
    strcpy(str,text);
    aStruct->p = str;
}

int main(){
    MyStruct_t example;
    createMyStruct(&example, "Hi!");
    printf("%s\n", example.p);
    return 0;
}

What am I getting wrong?

like image 709
MaxPowell Avatar asked Apr 19 '26 17:04

MaxPowell


1 Answers

This is an error:

this.myString = std::string(aString);

It should be this->myString. (I have heard there is a compiler that implements using . on pointers as an extension... uggh)

Anyway, the effects of this line are:

  1. Create a temporary object of type std::string, initialized by passing aString to its constructor. That constructor copies from your char * into memory which the std::string constructor allocates within the temporary object. A std::string object internally contains a pointer to some allocated storage; it doesn't refer to your string literal any more after this step.
  2. Call this->myString::operator=(std::string const &), where the temporary object binds to the const reference. The std::string::operator= function increases the memory allocation in the target string, and copies bytes over from the source string. (It doesn't "share" the allocation or anything).
  3. Destruct the temporary object (and std::string's destructor deletes the pointer to its storage for the string contents).

The end result is that the string contents get copied by value into myString , there are no memory leaks. After Step 2, there are briefly two copies in memory of the string contents.

Note that the compiler may optimize all stages of this process, so if you inspect your generated assembly it may look different. But conceptually, this is the defined list of steps.

I guess you might be coming from Java... if so, C++ has automatic allocation for all data types (whereas Java only has it for primitive types). You can go T(args) anywhere you like, and create a temporary T which lives until the end of the full-expression in which it was created.

like image 193
M.M Avatar answered Apr 22 '26 05:04

M.M



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!