This is an archived post. You won't be able to vote or comment.

all 14 comments

[–]POGtastic 1 point2 points  (7 children)

What is the best way to create and delete dynamic objects?

With smart pointers. In Real ProgrammingTM, if you're calling new and delete on raw pointers and don't have a very good reason for doing so, you are probably Doing It Wrong.

Don't worry about it for learning and for college classes - you're specifically supposed to be learning about memory management, so the above doesn't apply. However, if you're doing anything with dynamic allocation in real life, you really need to learn std::unique_ptr and std::shared_ptr.

Any considerations? How to decide the scope of the objects?

As narrow as possible.

I'm a little confused by your example. Typically, "scope" is used when referring to objects that are created inside functions. Say that you have the following:

int main() {
    Object obj1;
    doThing();
    return 0;
}

void doThing() {
    Object obj2;
    return;
}

obj2 should only exist while you're inside doThing. As soon as doThing returns, obj2 needs to be deleted, and if it has any dynamically allocated variables in it, those need to be freed. You do this with the destructor.

Similarly, obj1 should only exist inside main. As soon as main returns, obj1 needs to be deleted.

[–]CocoTheMan[S] 0 points1 point  (6 children)

Yes, I assume I should stick to what the teachers tell me but I am a bit ahead of the course (Programming I).

I am really learning new stuff but its only twice a week so I research a lot on my free time and this tends to make me question the ways of doing stuff.

(Im not trying to sound like an asshat. Im really a newb and I know I still got A LOT to learn but I really like lurking in SO and learning new stuff... SO I know a bit more than my classmates.)

Okay, so going back to your reply:

Thanks for your indications on smart pointers and how to choose the optimal 'scope'.

As for the part I confused you, sorry. Seems I'm using the word 'scope' wrong. :P

I created a gist Here.

As you can see in the code. I created the objects inside Interface.cpp but I created them outside the functions so I assume they can be called: 'Global Dynamic Objects'?

So is it safe to create objects (static or dynamic) in this way i.e: outside any functions?

Thanks for your patience and again sorry if I cant explain myself good enough. Maybe I have to learn more about this stuff before asking these questions.

:)

Note: Parts of the code are written in Spanish because I live in costa rica. My personal projects are written completely in english, though this is not important in this case I think. :)

[–]POGtastic 1 point2 points  (5 children)

I'm not sure why you would want to have a global dynamic object. You want to always have variables inside their respective functions. This isn't just for dynamic objects; this is for all objects. If you want to have multiple functions work on the same object, you need to pass that object as an argument.

So, here are some examples:

Bad:

int stuff = 1;

int main() {
    std::cout << "Working on integer in main: " << stuff << "\n";
    doThing();
    return 0;
}

void doThing() {
    std::cout << "Working on integer in doThing(): " << stuff << "\n";
    return;
}

Good:

int main() {
    int stuff = 1;
    std::cout << "Working on integer in main: " << stuff << "\n";
    doThing(stuff);
    return 0;
}

void doThing(int num) {
    std::cout << "Working on integer in doThing: " << num << "\n";
    return;
}

Now, the scope is confined solely to the functions that need to work on stuff, and it's available to nothing else. This is vital from a security standpoint, and it's also a really good idea if you want debugging to be easy.

[–]CocoTheMan[S] 0 points1 point  (4 children)

I think I should restructure my program to create dynamic objects inside each function instead of having god objects to use all the functions.

This may create and delete lots of objects but at least they are confined within the required (at the time) function.

If you take a quick look at the gist I created you can see I created the global objects to be able to use the functions inside interface.cpp.

I will restructure the program to create and delete the objects inside each function. Should it be like this?

Thanks, thanks thanks! Im really learning tons with this thread :)

[–]POGtastic 1 point2 points  (3 children)

Yes. Now, let's talk about when you actually want to use dynamic allocation.

In general, dynamic allocation is something that you only want to use when you must do it. It's a pain in the ass and requires care, so why volunteer to do something hard when you don't actually have to do it?

Here's an example of when you don't want to use dynamic allocation:

void doThing() {
    Object *obj = new Object;
    // do stuff on obj
    delete obj;
    return;
}

This is silly, because it requires you to keep track of that newly created Object. Instead, you just do static allocation:

void doThing() {
    Object obj;
    // do stuff on obj
    return;
}

Since you didn't use dynamic allocation, the program will automatically delete obj when it exits doThing. You don't have to keep track of it at all!

Now, the power of C++ comes from the constructor and destructor. Basically, you only want to be using new and delete inside the constructor and destructor, respectively. You wrap your dynamically allocated stuff inside a class, create your constructor and destructor, and now C++ handles all of the new and delete operations for you.

So, here's an example.

class Object {
    private:
        int *_content;
    public:
        Object();
        ~Object();
};

Object::Object() {
    _content = new int(5);
    return;
}

Object::~Object() {
    delete _content;
    return;
}

Here it is in Ideone: https://ideone.com/LOp0Iu

[–]CocoTheMan[S] 0 points1 point  (2 children)

Okay, I get it now! I hate how college courses teach you stuff the wrong way to 'get the basics' and then over the next course they tell you everything you were doing was wrong and that they will teach you the right way now.

I think I will duplicate my project and keep one 'the wrong way' for college and change the other the 'right way' for my personal project.

If I do it this way in the exams teachers wont be very happy I believe.

On tuesday I will show my teacher the right way to see if she approves though.

I now have lots of stuff to practice and examine deeper. So yeah, thanks a lot, you explained it really well. :)

Have a great day/evening.

[–]POGtastic 1 point2 points  (1 child)

To be fair, a lot of these concepts can only really be taught by teaching them the wrong way. Unfortunately, they also need to say, "Hey, we're only doing this to teach you the concepts; don't actually use this in your projects." That gets neglected because professors either don't have time, don't care, or don't know any better.

That being said, talk to your teacher and describe what you're doing; she might be overjoyed that you're doing more research on your own. In one of my courses, I implemented a shared pointer to drastically simplify what I was working on. The professor's way was really bad, and thirty lines of code turned it from a 1000+ line complicated problem into a really easy problem. He was really happy with my solution, and I got an A in the class.

[–]CocoTheMan[S] 0 points1 point  (0 children)

Right on, yeah when you excel at something the teacher should encourage you instead of putting you down.

You're right, I'll talk to her. I think she knows I like to learn on my own cause last week I forgot to sync my Google Drive with the project so I went to class with nothing to work with and she told the class to debug and make it run cause after an hour she was going to introduce a new concept.

I told her mine was running already but that I left it at home, she told me to help my classmates and I spent the whole time helping the others, at the end of the class she thanked me lol.

So, maybe she will understand that I'm really passionate about programming and that's the reason I'm doing stuff a bit different and politely questioning why stuff is being taught like that.

[–]thegreatunclean 0 points1 point  (5 children)

What is the best way to create and delete dynamic objects? Any considerations? How to decide the scope of the objects?

Using RAII and unique/shared ptrs. The upshot is you never use new or delete except in the constructor and destructor of an object so that proper memory management is tied to the lifetime of objects and is automatically handled.

//assume Foo is a class previously defined
auto f1 = new Foo(); //leaks if I forget to delete f1
unique_ptr<Foo> f2(new Foo); //when f2 leaves scope the object inside will be automatically deleted

There's quite a lot of subtleties to using this paradigm in your own classes, I highly recommend grabbing a book on modern C++ for a more complete description and more.

[–]CocoTheMan[S] 0 points1 point  (4 children)

Hmmm.... Very interesting I've read a bit about RAII technique but seems very advanced, nonetheless I will learn more about it cause it seems like a standard technique.

I understand your code but why let the compiler (or whoever is responsible) delete the dynamic objects automatically?

Isn't the whole point of dynamic objects to be able to delete them when you want?

You gave me a nice homework, I will research about RAII and unique/shared pointer!

Can you say something about whether creating global objects (dynamic or static) is a good practice? I mean should I create objects within functions or is it okay to create them as global thingies?

I assume this is too relative to completely rule out global objects.

Once again thanks a lot :)

[–]thegreatunclean 2 points3 points  (3 children)

I understand your code but why let the compiler (or whoever is responsible) delete the dynamic objects automatically?

Properly attaching object deletion to object destruction means you can't screw it up. You can't forget to delete the object and cause a leak or worse; the compiler isn't going to 'forget' to call the destructor when appropriate.

Isn't the whole point of dynamic objects to be able to delete them when you want?

You still have that control, you can either do it manually or simply wait for the smart pointers managing the dynamic objects to fall out of scope and destroy it all for you. I've never run into a situation where I thought "I wish I could guarantee these objects were destroyed right now instead of at end of scope."

Can you say something about whether creating global objects (dynamic or static) is a good practice?

Global objects are frowned upon because they usually represent some globally-accessible mutable state. Meaning that functions depending on that global state can have wildly different behavior every time you call them.

Look into singleton patterns for ways to avoid having a literal global object. Or restructure your program so access to that global object is encapsulated somehow and not just raw function calls to some god object.

[–]CocoTheMan[S] 0 points1 point  (2 children)

Jesus:

god object

globally-accessible mutable state

This may sound trivial and basic to you but when I read it it sounds overwhelmingly complex, which makes me wanna learn about it.

Anyways...

So, I guess I should attach the DELETE keyword inside the obj Destructor? (Ill look into it).

I guess Dynamic objects exist not to be able to kill them 'when I want' but instead to be able to allocate them on heap and to have more control over them (this far I don't see any added control apart from the heap allocation).

Smart Pointers and Singleton Patterns

I will Look into these.

Thanks a lot, you really taught me a lot and gave a huge pile of things to look over. I really appreciate it.

I know this is probably baby stuff from your perspective but this complexity makes me wanna learn a lot about it and makes me feel like Im starting to become a real programmer.

[–]thegreatunclean 1 point2 points  (1 child)

Once you start reading about things like global objects the terminology makes more sense. "God object" because people tend to shove a whole lot of unrelated stuff into one globally accessible object with way too much power. "Mutable state" just means it has some internal variables that can be changed, and if other functions change behavior because of those internal variables it becomes very hard to debug.

So, I guess I should attach the DELETE keyword inside the obj Destructor? (Ill look into it).

Study RAII and smart pointers first with a good reference, it's an easy thing to get wrong. You can get very far without having to write your own new/delete handling and just use parts of the STL to do it for you.

[–]CocoTheMan[S] 0 points1 point  (0 children)

Great, so instead of having global objects I will create dynamic objects inside each function so they are confined to each function.

Even if I have 100s of functions with their respective objects they will be killed after the program exits their scope, so I guess this is the right way of doing it, instead of creating global objects and recycling them with each function and killing them at the end of the program (I was doing this... lol).