Memory leaks in a pointer vector










0















I'm making a program that uses plenty of vectors containing pointers and I'm concerned that the way i delete the pointers might cause memory leaks down the line.



Here's for example how I add a bullet to the vector:



Bullet* aNewBullet;
aNewBullet = new Bullet(x,y,dirX,dirY,size,duration);
aNewBullet->assignTexture(btext);
bulletVector.push_back(aNewBullet);


And here's how i delete bullets from the vector (for example, if it exceeds its range)



int i=0;
while (i<bulletVector.size())
if (bulletVector[i]->getDuration() ==0)
bulletVector.erase(bulletVector.begin() + i);
else i++;



Am I deleting the bullet by telling the vector to erase?
Or should i do



int i=0;
while (i<bulletVector.size())
if (bulletVector[i]->getDuration() ==0)
delete bulletVector[i];
bulletVector.erase(bulletVector.begin() + i);
else i++;



instead? Does this mess up the vector size by deleting the pointer first, and then deleting the record from the vector again?



Also does deleting the pointer call the bullet destructor (~Bullet())?










share|improve this question

















  • 3





    Do you need to use new/delete? Why not just use std::vector<Bullet>?

    – CoryKramer
    Nov 15 '18 at 13:52











  • Collections of raw pointers are just not a good idea. Either the collection owns the objects pointed to or it doesn't. If it does own them, why use pointers at all? If it doesn't own them, managing the lifetime of the objects becomes very complicated.

    – David Schwartz
    Nov 15 '18 at 14:42















0















I'm making a program that uses plenty of vectors containing pointers and I'm concerned that the way i delete the pointers might cause memory leaks down the line.



Here's for example how I add a bullet to the vector:



Bullet* aNewBullet;
aNewBullet = new Bullet(x,y,dirX,dirY,size,duration);
aNewBullet->assignTexture(btext);
bulletVector.push_back(aNewBullet);


And here's how i delete bullets from the vector (for example, if it exceeds its range)



int i=0;
while (i<bulletVector.size())
if (bulletVector[i]->getDuration() ==0)
bulletVector.erase(bulletVector.begin() + i);
else i++;



Am I deleting the bullet by telling the vector to erase?
Or should i do



int i=0;
while (i<bulletVector.size())
if (bulletVector[i]->getDuration() ==0)
delete bulletVector[i];
bulletVector.erase(bulletVector.begin() + i);
else i++;



instead? Does this mess up the vector size by deleting the pointer first, and then deleting the record from the vector again?



Also does deleting the pointer call the bullet destructor (~Bullet())?










share|improve this question

















  • 3





    Do you need to use new/delete? Why not just use std::vector<Bullet>?

    – CoryKramer
    Nov 15 '18 at 13:52











  • Collections of raw pointers are just not a good idea. Either the collection owns the objects pointed to or it doesn't. If it does own them, why use pointers at all? If it doesn't own them, managing the lifetime of the objects becomes very complicated.

    – David Schwartz
    Nov 15 '18 at 14:42













0












0








0








I'm making a program that uses plenty of vectors containing pointers and I'm concerned that the way i delete the pointers might cause memory leaks down the line.



Here's for example how I add a bullet to the vector:



Bullet* aNewBullet;
aNewBullet = new Bullet(x,y,dirX,dirY,size,duration);
aNewBullet->assignTexture(btext);
bulletVector.push_back(aNewBullet);


And here's how i delete bullets from the vector (for example, if it exceeds its range)



int i=0;
while (i<bulletVector.size())
if (bulletVector[i]->getDuration() ==0)
bulletVector.erase(bulletVector.begin() + i);
else i++;



Am I deleting the bullet by telling the vector to erase?
Or should i do



int i=0;
while (i<bulletVector.size())
if (bulletVector[i]->getDuration() ==0)
delete bulletVector[i];
bulletVector.erase(bulletVector.begin() + i);
else i++;



instead? Does this mess up the vector size by deleting the pointer first, and then deleting the record from the vector again?



Also does deleting the pointer call the bullet destructor (~Bullet())?










share|improve this question














I'm making a program that uses plenty of vectors containing pointers and I'm concerned that the way i delete the pointers might cause memory leaks down the line.



Here's for example how I add a bullet to the vector:



Bullet* aNewBullet;
aNewBullet = new Bullet(x,y,dirX,dirY,size,duration);
aNewBullet->assignTexture(btext);
bulletVector.push_back(aNewBullet);


And here's how i delete bullets from the vector (for example, if it exceeds its range)



int i=0;
while (i<bulletVector.size())
if (bulletVector[i]->getDuration() ==0)
bulletVector.erase(bulletVector.begin() + i);
else i++;



Am I deleting the bullet by telling the vector to erase?
Or should i do



int i=0;
while (i<bulletVector.size())
if (bulletVector[i]->getDuration() ==0)
delete bulletVector[i];
bulletVector.erase(bulletVector.begin() + i);
else i++;



instead? Does this mess up the vector size by deleting the pointer first, and then deleting the record from the vector again?



Also does deleting the pointer call the bullet destructor (~Bullet())?







c++ pointers vector memory-leaks






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 15 '18 at 13:51









martincitomartincito

163




163







  • 3





    Do you need to use new/delete? Why not just use std::vector<Bullet>?

    – CoryKramer
    Nov 15 '18 at 13:52











  • Collections of raw pointers are just not a good idea. Either the collection owns the objects pointed to or it doesn't. If it does own them, why use pointers at all? If it doesn't own them, managing the lifetime of the objects becomes very complicated.

    – David Schwartz
    Nov 15 '18 at 14:42












  • 3





    Do you need to use new/delete? Why not just use std::vector<Bullet>?

    – CoryKramer
    Nov 15 '18 at 13:52











  • Collections of raw pointers are just not a good idea. Either the collection owns the objects pointed to or it doesn't. If it does own them, why use pointers at all? If it doesn't own them, managing the lifetime of the objects becomes very complicated.

    – David Schwartz
    Nov 15 '18 at 14:42







3




3





Do you need to use new/delete? Why not just use std::vector<Bullet>?

– CoryKramer
Nov 15 '18 at 13:52





Do you need to use new/delete? Why not just use std::vector<Bullet>?

– CoryKramer
Nov 15 '18 at 13:52













Collections of raw pointers are just not a good idea. Either the collection owns the objects pointed to or it doesn't. If it does own them, why use pointers at all? If it doesn't own them, managing the lifetime of the objects becomes very complicated.

– David Schwartz
Nov 15 '18 at 14:42





Collections of raw pointers are just not a good idea. Either the collection owns the objects pointed to or it doesn't. If it does own them, why use pointers at all? If it doesn't own them, managing the lifetime of the objects becomes very complicated.

– David Schwartz
Nov 15 '18 at 14:42












4 Answers
4






active

oldest

votes


















2














In the first code example you are not deleting any Bullet object. Erasing vector does only remove the pointers, not delete the pointed to object.



Your second example does properly delete Bullets (not all of them given the conditionals and loop setup), but only if you do the necessary deletion at all points where the vector is modified and manually assure that a pointer is never deleted twice (e.g. because it is present in two vectors). This is not how containers are supposed to be used.



If you really want to store pointers and have the vector own them, then you should use std::vector<std::unique_ptr<Bullet>> which will properly delete the Bullet objects when the vector is erased. However the vector will become non-copyable (only movable).



If however the vector is supposed own the Bullets anyway, then you can simply store them directly in the vector: std::vector<Bullet>



If the vector is not supposed to own the Bullets then the duty to delete them lies with whatever object is actually owning them, but even then there needs to be some effort made to assure deleted pointers do not remain in the vector.






share|improve this answer
































    1














    You need to delete the objects you've created with new (unless you surrender the pointer to a std::unique_ptr or std::shared_ptr). Consider letting the vector be the owner of the objects instead.



    std::vector<Bullet> bulletVector;

    // in C++17, emplace_back returns a ref to the new Bullet:
    Bullet& aNewBullet = bulletVector.emplace_back(x,y,dirX,dirY,size,duration);

    // pre C++17:
    bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
    Bullet& aNewBullet = bulletVector.back();

    aNewBullet.assignTexture(btext);


    When you now erase() an object from the vector, it will be destructed automatically.






    share|improve this answer























    • the vector is declared as vector<Bullet*> bulletVector; in the class, is removing the asterisk correct?

      – martincito
      Nov 15 '18 at 14:27











    • No, I suggested that OP should consider declaring it std::vector<Bullet> bulletVector; instead - if it doesn't mess up the rest of the design of course.

      – Ted Lyngmo
      Nov 15 '18 at 14:36


















    1














    First, it is highly likely you problem is solvable by not using manual dynamic allocation in the first place. There are reasons where you can use dynamic allocation (a polymorphic storage, for example), but even then you should steer toward smart pointers rather than manual allocations.



    Ditch the pointers



    To do this with a regular vector of concrete objects (not pointers), you would simply



    std::vector<Bullet> bulletVector;


    Additions could be done with something like this:



    bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
    bulletVector.back().assignTexture(btext);


    Removing all elements based on duration reaching zero would simply use the remove/erase idiom like this:



    bulletVector.erase(std::remove_if(
    bulletVector.begin(),
    bulletVector.end(),
    (auto const& b) return b.getDuration() == 0; ),
    bulletVector.end());


    Keep in mind, while this is easily the preferred method for storing these things, it will require changes in the rest of your code. Everywhere you currently do this:



    bulletVector[i]->doSomething();


    will become



    bulletVector[i].doSomething();



    More Intelligent Pointers



    If you must use dynamic allocation, don't use manually managed pointers. They're a recipe for memory leaks and ownership responsibility, and if you think it can't happen to you, you're being naive. Rather, use smart pointers. The two main smart pointer templates are std::unique_ptr and std::shared_ptr. There is also std::weak_ptr, which deserve an honorable mention, as it comes in very handy in certain situations (not yours, that I can tell).



    std::vector<std::shared_ptr<Bullet>> bulletVector;


    Hence additions can be done like this (assuming this is done with polymorphism in mind and there may be more than one bullet type, in this case MagicBullet and SilverBullet, both derived from Bullet):



    std::shared_ptr<Bullet> bullet = std::make_shared<MagicBullet>(x,y,dirX,dirY,size,duration);
    bullet->assignTexture(btext);
    bulletVector.emplace_back(bullet);

    bullet = std::make_shared<SilverBullet>(x,y,dirX,dirY,size,duration);
    bullet->assignTexture(btext);
    bulletVector.emplace_back(bullet);


    or just store regular bullets:



    bullet = std::make_shared<Bullet>(x,y,dirX,dirY,size,duration);
    bullet->assignTexture(btext);
    bulletVector.emplace_back(bullet);


    The removal algorithm is identical, only the condition predicate function changes (and not by much)



    bulletVector.erase(std::remove_if(
    bulletVector.begin(),
    bulletVector.end(),
    (auto const& b) return b->getDuration() == 0; ),
    bulletVector.end());


    The nicest part of this is the remainder of your code will likely require little to no changes whatsoever. But I stress, that's the only real benefit (apart form the obvious, namely not having to manage the memory yourself any longer).




    Given the choice between the two methods (vector of concrete objects vs vector of smart pointers) choose carefully. If the former works, use it. If it doesn't, either think about how it could work, or use the latter.



    But above all, stop managing memory manually.






    share|improve this answer























    • Personally I would want to recommend std::unique_ptr over std::shared_ptr as std::shared_ptrs come with their own set of problems and should only be used when actual shared ownership is required (two or more objects need to reference the same object and it is impossible to know which will die last).

      – Galik
      Nov 15 '18 at 16:25











    • @Galik Certainly the appropriate use case should use the appropriate pointer type. There is zero evidence in the OP's code that the instances will be unique, and shared will work in both cases. If they indeed are unique, then the only reason to use a smart pointer at all (as opposed to concrete objects) is for polymorphic reasons (which there is likewise, zero evidence is required, but is an important unknown). Regardless, the concept is the same.

      – WhozCraig
      Nov 15 '18 at 17:00


















    -1














    Of course, you must deleting Bullets by yourself by delete. But your deletion cycle is not correct.



    To delete values from vector with some condition, use something like this:



    auto condFunc = (const Bullet* x)

    bool rez = (x->getDuration() == 0);
    if(rez)
    delete x;
    return rez;
    ;
    bulletVector.erase(std::remove_if(bulletVector.begin(), bulletVector.end(), condFunc), bulletVector.end());





    share|improve this answer

























    • Your example code doesn't delete the pointees either though, despite being a nicer way to erase them from the vector.

      – Pete Kirkham
      Nov 15 '18 at 14:13











    • @PeteKirkham this example was "To delete values from vector", not to free memory

      – snake_style
      Nov 15 '18 at 14:25











    • In that case it doesn't answer the question, which was about both removing them from the vector and deleting them from the heap. In C++ there is no such thing as 'deleting values from a vector' as 'delete' has a very specific meaning.

      – Pete Kirkham
      Nov 15 '18 at 14:34










    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53320959%2fmemory-leaks-in-a-pointer-vector%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    In the first code example you are not deleting any Bullet object. Erasing vector does only remove the pointers, not delete the pointed to object.



    Your second example does properly delete Bullets (not all of them given the conditionals and loop setup), but only if you do the necessary deletion at all points where the vector is modified and manually assure that a pointer is never deleted twice (e.g. because it is present in two vectors). This is not how containers are supposed to be used.



    If you really want to store pointers and have the vector own them, then you should use std::vector<std::unique_ptr<Bullet>> which will properly delete the Bullet objects when the vector is erased. However the vector will become non-copyable (only movable).



    If however the vector is supposed own the Bullets anyway, then you can simply store them directly in the vector: std::vector<Bullet>



    If the vector is not supposed to own the Bullets then the duty to delete them lies with whatever object is actually owning them, but even then there needs to be some effort made to assure deleted pointers do not remain in the vector.






    share|improve this answer





























      2














      In the first code example you are not deleting any Bullet object. Erasing vector does only remove the pointers, not delete the pointed to object.



      Your second example does properly delete Bullets (not all of them given the conditionals and loop setup), but only if you do the necessary deletion at all points where the vector is modified and manually assure that a pointer is never deleted twice (e.g. because it is present in two vectors). This is not how containers are supposed to be used.



      If you really want to store pointers and have the vector own them, then you should use std::vector<std::unique_ptr<Bullet>> which will properly delete the Bullet objects when the vector is erased. However the vector will become non-copyable (only movable).



      If however the vector is supposed own the Bullets anyway, then you can simply store them directly in the vector: std::vector<Bullet>



      If the vector is not supposed to own the Bullets then the duty to delete them lies with whatever object is actually owning them, but even then there needs to be some effort made to assure deleted pointers do not remain in the vector.






      share|improve this answer



























        2












        2








        2







        In the first code example you are not deleting any Bullet object. Erasing vector does only remove the pointers, not delete the pointed to object.



        Your second example does properly delete Bullets (not all of them given the conditionals and loop setup), but only if you do the necessary deletion at all points where the vector is modified and manually assure that a pointer is never deleted twice (e.g. because it is present in two vectors). This is not how containers are supposed to be used.



        If you really want to store pointers and have the vector own them, then you should use std::vector<std::unique_ptr<Bullet>> which will properly delete the Bullet objects when the vector is erased. However the vector will become non-copyable (only movable).



        If however the vector is supposed own the Bullets anyway, then you can simply store them directly in the vector: std::vector<Bullet>



        If the vector is not supposed to own the Bullets then the duty to delete them lies with whatever object is actually owning them, but even then there needs to be some effort made to assure deleted pointers do not remain in the vector.






        share|improve this answer















        In the first code example you are not deleting any Bullet object. Erasing vector does only remove the pointers, not delete the pointed to object.



        Your second example does properly delete Bullets (not all of them given the conditionals and loop setup), but only if you do the necessary deletion at all points where the vector is modified and manually assure that a pointer is never deleted twice (e.g. because it is present in two vectors). This is not how containers are supposed to be used.



        If you really want to store pointers and have the vector own them, then you should use std::vector<std::unique_ptr<Bullet>> which will properly delete the Bullet objects when the vector is erased. However the vector will become non-copyable (only movable).



        If however the vector is supposed own the Bullets anyway, then you can simply store them directly in the vector: std::vector<Bullet>



        If the vector is not supposed to own the Bullets then the duty to delete them lies with whatever object is actually owning them, but even then there needs to be some effort made to assure deleted pointers do not remain in the vector.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 15 '18 at 14:06

























        answered Nov 15 '18 at 13:59









        user10605163user10605163

        2,868624




        2,868624























            1














            You need to delete the objects you've created with new (unless you surrender the pointer to a std::unique_ptr or std::shared_ptr). Consider letting the vector be the owner of the objects instead.



            std::vector<Bullet> bulletVector;

            // in C++17, emplace_back returns a ref to the new Bullet:
            Bullet& aNewBullet = bulletVector.emplace_back(x,y,dirX,dirY,size,duration);

            // pre C++17:
            bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
            Bullet& aNewBullet = bulletVector.back();

            aNewBullet.assignTexture(btext);


            When you now erase() an object from the vector, it will be destructed automatically.






            share|improve this answer























            • the vector is declared as vector<Bullet*> bulletVector; in the class, is removing the asterisk correct?

              – martincito
              Nov 15 '18 at 14:27











            • No, I suggested that OP should consider declaring it std::vector<Bullet> bulletVector; instead - if it doesn't mess up the rest of the design of course.

              – Ted Lyngmo
              Nov 15 '18 at 14:36















            1














            You need to delete the objects you've created with new (unless you surrender the pointer to a std::unique_ptr or std::shared_ptr). Consider letting the vector be the owner of the objects instead.



            std::vector<Bullet> bulletVector;

            // in C++17, emplace_back returns a ref to the new Bullet:
            Bullet& aNewBullet = bulletVector.emplace_back(x,y,dirX,dirY,size,duration);

            // pre C++17:
            bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
            Bullet& aNewBullet = bulletVector.back();

            aNewBullet.assignTexture(btext);


            When you now erase() an object from the vector, it will be destructed automatically.






            share|improve this answer























            • the vector is declared as vector<Bullet*> bulletVector; in the class, is removing the asterisk correct?

              – martincito
              Nov 15 '18 at 14:27











            • No, I suggested that OP should consider declaring it std::vector<Bullet> bulletVector; instead - if it doesn't mess up the rest of the design of course.

              – Ted Lyngmo
              Nov 15 '18 at 14:36













            1












            1








            1







            You need to delete the objects you've created with new (unless you surrender the pointer to a std::unique_ptr or std::shared_ptr). Consider letting the vector be the owner of the objects instead.



            std::vector<Bullet> bulletVector;

            // in C++17, emplace_back returns a ref to the new Bullet:
            Bullet& aNewBullet = bulletVector.emplace_back(x,y,dirX,dirY,size,duration);

            // pre C++17:
            bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
            Bullet& aNewBullet = bulletVector.back();

            aNewBullet.assignTexture(btext);


            When you now erase() an object from the vector, it will be destructed automatically.






            share|improve this answer













            You need to delete the objects you've created with new (unless you surrender the pointer to a std::unique_ptr or std::shared_ptr). Consider letting the vector be the owner of the objects instead.



            std::vector<Bullet> bulletVector;

            // in C++17, emplace_back returns a ref to the new Bullet:
            Bullet& aNewBullet = bulletVector.emplace_back(x,y,dirX,dirY,size,duration);

            // pre C++17:
            bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
            Bullet& aNewBullet = bulletVector.back();

            aNewBullet.assignTexture(btext);


            When you now erase() an object from the vector, it will be destructed automatically.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 15 '18 at 14:08









            Ted LyngmoTed Lyngmo

            3,1072518




            3,1072518












            • the vector is declared as vector<Bullet*> bulletVector; in the class, is removing the asterisk correct?

              – martincito
              Nov 15 '18 at 14:27











            • No, I suggested that OP should consider declaring it std::vector<Bullet> bulletVector; instead - if it doesn't mess up the rest of the design of course.

              – Ted Lyngmo
              Nov 15 '18 at 14:36

















            • the vector is declared as vector<Bullet*> bulletVector; in the class, is removing the asterisk correct?

              – martincito
              Nov 15 '18 at 14:27











            • No, I suggested that OP should consider declaring it std::vector<Bullet> bulletVector; instead - if it doesn't mess up the rest of the design of course.

              – Ted Lyngmo
              Nov 15 '18 at 14:36
















            the vector is declared as vector<Bullet*> bulletVector; in the class, is removing the asterisk correct?

            – martincito
            Nov 15 '18 at 14:27





            the vector is declared as vector<Bullet*> bulletVector; in the class, is removing the asterisk correct?

            – martincito
            Nov 15 '18 at 14:27













            No, I suggested that OP should consider declaring it std::vector<Bullet> bulletVector; instead - if it doesn't mess up the rest of the design of course.

            – Ted Lyngmo
            Nov 15 '18 at 14:36





            No, I suggested that OP should consider declaring it std::vector<Bullet> bulletVector; instead - if it doesn't mess up the rest of the design of course.

            – Ted Lyngmo
            Nov 15 '18 at 14:36











            1














            First, it is highly likely you problem is solvable by not using manual dynamic allocation in the first place. There are reasons where you can use dynamic allocation (a polymorphic storage, for example), but even then you should steer toward smart pointers rather than manual allocations.



            Ditch the pointers



            To do this with a regular vector of concrete objects (not pointers), you would simply



            std::vector<Bullet> bulletVector;


            Additions could be done with something like this:



            bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
            bulletVector.back().assignTexture(btext);


            Removing all elements based on duration reaching zero would simply use the remove/erase idiom like this:



            bulletVector.erase(std::remove_if(
            bulletVector.begin(),
            bulletVector.end(),
            (auto const& b) return b.getDuration() == 0; ),
            bulletVector.end());


            Keep in mind, while this is easily the preferred method for storing these things, it will require changes in the rest of your code. Everywhere you currently do this:



            bulletVector[i]->doSomething();


            will become



            bulletVector[i].doSomething();



            More Intelligent Pointers



            If you must use dynamic allocation, don't use manually managed pointers. They're a recipe for memory leaks and ownership responsibility, and if you think it can't happen to you, you're being naive. Rather, use smart pointers. The two main smart pointer templates are std::unique_ptr and std::shared_ptr. There is also std::weak_ptr, which deserve an honorable mention, as it comes in very handy in certain situations (not yours, that I can tell).



            std::vector<std::shared_ptr<Bullet>> bulletVector;


            Hence additions can be done like this (assuming this is done with polymorphism in mind and there may be more than one bullet type, in this case MagicBullet and SilverBullet, both derived from Bullet):



            std::shared_ptr<Bullet> bullet = std::make_shared<MagicBullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);

            bullet = std::make_shared<SilverBullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);


            or just store regular bullets:



            bullet = std::make_shared<Bullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);


            The removal algorithm is identical, only the condition predicate function changes (and not by much)



            bulletVector.erase(std::remove_if(
            bulletVector.begin(),
            bulletVector.end(),
            (auto const& b) return b->getDuration() == 0; ),
            bulletVector.end());


            The nicest part of this is the remainder of your code will likely require little to no changes whatsoever. But I stress, that's the only real benefit (apart form the obvious, namely not having to manage the memory yourself any longer).




            Given the choice between the two methods (vector of concrete objects vs vector of smart pointers) choose carefully. If the former works, use it. If it doesn't, either think about how it could work, or use the latter.



            But above all, stop managing memory manually.






            share|improve this answer























            • Personally I would want to recommend std::unique_ptr over std::shared_ptr as std::shared_ptrs come with their own set of problems and should only be used when actual shared ownership is required (two or more objects need to reference the same object and it is impossible to know which will die last).

              – Galik
              Nov 15 '18 at 16:25











            • @Galik Certainly the appropriate use case should use the appropriate pointer type. There is zero evidence in the OP's code that the instances will be unique, and shared will work in both cases. If they indeed are unique, then the only reason to use a smart pointer at all (as opposed to concrete objects) is for polymorphic reasons (which there is likewise, zero evidence is required, but is an important unknown). Regardless, the concept is the same.

              – WhozCraig
              Nov 15 '18 at 17:00















            1














            First, it is highly likely you problem is solvable by not using manual dynamic allocation in the first place. There are reasons where you can use dynamic allocation (a polymorphic storage, for example), but even then you should steer toward smart pointers rather than manual allocations.



            Ditch the pointers



            To do this with a regular vector of concrete objects (not pointers), you would simply



            std::vector<Bullet> bulletVector;


            Additions could be done with something like this:



            bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
            bulletVector.back().assignTexture(btext);


            Removing all elements based on duration reaching zero would simply use the remove/erase idiom like this:



            bulletVector.erase(std::remove_if(
            bulletVector.begin(),
            bulletVector.end(),
            (auto const& b) return b.getDuration() == 0; ),
            bulletVector.end());


            Keep in mind, while this is easily the preferred method for storing these things, it will require changes in the rest of your code. Everywhere you currently do this:



            bulletVector[i]->doSomething();


            will become



            bulletVector[i].doSomething();



            More Intelligent Pointers



            If you must use dynamic allocation, don't use manually managed pointers. They're a recipe for memory leaks and ownership responsibility, and if you think it can't happen to you, you're being naive. Rather, use smart pointers. The two main smart pointer templates are std::unique_ptr and std::shared_ptr. There is also std::weak_ptr, which deserve an honorable mention, as it comes in very handy in certain situations (not yours, that I can tell).



            std::vector<std::shared_ptr<Bullet>> bulletVector;


            Hence additions can be done like this (assuming this is done with polymorphism in mind and there may be more than one bullet type, in this case MagicBullet and SilverBullet, both derived from Bullet):



            std::shared_ptr<Bullet> bullet = std::make_shared<MagicBullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);

            bullet = std::make_shared<SilverBullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);


            or just store regular bullets:



            bullet = std::make_shared<Bullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);


            The removal algorithm is identical, only the condition predicate function changes (and not by much)



            bulletVector.erase(std::remove_if(
            bulletVector.begin(),
            bulletVector.end(),
            (auto const& b) return b->getDuration() == 0; ),
            bulletVector.end());


            The nicest part of this is the remainder of your code will likely require little to no changes whatsoever. But I stress, that's the only real benefit (apart form the obvious, namely not having to manage the memory yourself any longer).




            Given the choice between the two methods (vector of concrete objects vs vector of smart pointers) choose carefully. If the former works, use it. If it doesn't, either think about how it could work, or use the latter.



            But above all, stop managing memory manually.






            share|improve this answer























            • Personally I would want to recommend std::unique_ptr over std::shared_ptr as std::shared_ptrs come with their own set of problems and should only be used when actual shared ownership is required (two or more objects need to reference the same object and it is impossible to know which will die last).

              – Galik
              Nov 15 '18 at 16:25











            • @Galik Certainly the appropriate use case should use the appropriate pointer type. There is zero evidence in the OP's code that the instances will be unique, and shared will work in both cases. If they indeed are unique, then the only reason to use a smart pointer at all (as opposed to concrete objects) is for polymorphic reasons (which there is likewise, zero evidence is required, but is an important unknown). Regardless, the concept is the same.

              – WhozCraig
              Nov 15 '18 at 17:00













            1












            1








            1







            First, it is highly likely you problem is solvable by not using manual dynamic allocation in the first place. There are reasons where you can use dynamic allocation (a polymorphic storage, for example), but even then you should steer toward smart pointers rather than manual allocations.



            Ditch the pointers



            To do this with a regular vector of concrete objects (not pointers), you would simply



            std::vector<Bullet> bulletVector;


            Additions could be done with something like this:



            bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
            bulletVector.back().assignTexture(btext);


            Removing all elements based on duration reaching zero would simply use the remove/erase idiom like this:



            bulletVector.erase(std::remove_if(
            bulletVector.begin(),
            bulletVector.end(),
            (auto const& b) return b.getDuration() == 0; ),
            bulletVector.end());


            Keep in mind, while this is easily the preferred method for storing these things, it will require changes in the rest of your code. Everywhere you currently do this:



            bulletVector[i]->doSomething();


            will become



            bulletVector[i].doSomething();



            More Intelligent Pointers



            If you must use dynamic allocation, don't use manually managed pointers. They're a recipe for memory leaks and ownership responsibility, and if you think it can't happen to you, you're being naive. Rather, use smart pointers. The two main smart pointer templates are std::unique_ptr and std::shared_ptr. There is also std::weak_ptr, which deserve an honorable mention, as it comes in very handy in certain situations (not yours, that I can tell).



            std::vector<std::shared_ptr<Bullet>> bulletVector;


            Hence additions can be done like this (assuming this is done with polymorphism in mind and there may be more than one bullet type, in this case MagicBullet and SilverBullet, both derived from Bullet):



            std::shared_ptr<Bullet> bullet = std::make_shared<MagicBullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);

            bullet = std::make_shared<SilverBullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);


            or just store regular bullets:



            bullet = std::make_shared<Bullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);


            The removal algorithm is identical, only the condition predicate function changes (and not by much)



            bulletVector.erase(std::remove_if(
            bulletVector.begin(),
            bulletVector.end(),
            (auto const& b) return b->getDuration() == 0; ),
            bulletVector.end());


            The nicest part of this is the remainder of your code will likely require little to no changes whatsoever. But I stress, that's the only real benefit (apart form the obvious, namely not having to manage the memory yourself any longer).




            Given the choice between the two methods (vector of concrete objects vs vector of smart pointers) choose carefully. If the former works, use it. If it doesn't, either think about how it could work, or use the latter.



            But above all, stop managing memory manually.






            share|improve this answer













            First, it is highly likely you problem is solvable by not using manual dynamic allocation in the first place. There are reasons where you can use dynamic allocation (a polymorphic storage, for example), but even then you should steer toward smart pointers rather than manual allocations.



            Ditch the pointers



            To do this with a regular vector of concrete objects (not pointers), you would simply



            std::vector<Bullet> bulletVector;


            Additions could be done with something like this:



            bulletVector.emplace_back(x,y,dirX,dirY,size,duration);
            bulletVector.back().assignTexture(btext);


            Removing all elements based on duration reaching zero would simply use the remove/erase idiom like this:



            bulletVector.erase(std::remove_if(
            bulletVector.begin(),
            bulletVector.end(),
            (auto const& b) return b.getDuration() == 0; ),
            bulletVector.end());


            Keep in mind, while this is easily the preferred method for storing these things, it will require changes in the rest of your code. Everywhere you currently do this:



            bulletVector[i]->doSomething();


            will become



            bulletVector[i].doSomething();



            More Intelligent Pointers



            If you must use dynamic allocation, don't use manually managed pointers. They're a recipe for memory leaks and ownership responsibility, and if you think it can't happen to you, you're being naive. Rather, use smart pointers. The two main smart pointer templates are std::unique_ptr and std::shared_ptr. There is also std::weak_ptr, which deserve an honorable mention, as it comes in very handy in certain situations (not yours, that I can tell).



            std::vector<std::shared_ptr<Bullet>> bulletVector;


            Hence additions can be done like this (assuming this is done with polymorphism in mind and there may be more than one bullet type, in this case MagicBullet and SilverBullet, both derived from Bullet):



            std::shared_ptr<Bullet> bullet = std::make_shared<MagicBullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);

            bullet = std::make_shared<SilverBullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);


            or just store regular bullets:



            bullet = std::make_shared<Bullet>(x,y,dirX,dirY,size,duration);
            bullet->assignTexture(btext);
            bulletVector.emplace_back(bullet);


            The removal algorithm is identical, only the condition predicate function changes (and not by much)



            bulletVector.erase(std::remove_if(
            bulletVector.begin(),
            bulletVector.end(),
            (auto const& b) return b->getDuration() == 0; ),
            bulletVector.end());


            The nicest part of this is the remainder of your code will likely require little to no changes whatsoever. But I stress, that's the only real benefit (apart form the obvious, namely not having to manage the memory yourself any longer).




            Given the choice between the two methods (vector of concrete objects vs vector of smart pointers) choose carefully. If the former works, use it. If it doesn't, either think about how it could work, or use the latter.



            But above all, stop managing memory manually.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 15 '18 at 14:37









            WhozCraigWhozCraig

            51.5k958108




            51.5k958108












            • Personally I would want to recommend std::unique_ptr over std::shared_ptr as std::shared_ptrs come with their own set of problems and should only be used when actual shared ownership is required (two or more objects need to reference the same object and it is impossible to know which will die last).

              – Galik
              Nov 15 '18 at 16:25











            • @Galik Certainly the appropriate use case should use the appropriate pointer type. There is zero evidence in the OP's code that the instances will be unique, and shared will work in both cases. If they indeed are unique, then the only reason to use a smart pointer at all (as opposed to concrete objects) is for polymorphic reasons (which there is likewise, zero evidence is required, but is an important unknown). Regardless, the concept is the same.

              – WhozCraig
              Nov 15 '18 at 17:00

















            • Personally I would want to recommend std::unique_ptr over std::shared_ptr as std::shared_ptrs come with their own set of problems and should only be used when actual shared ownership is required (two or more objects need to reference the same object and it is impossible to know which will die last).

              – Galik
              Nov 15 '18 at 16:25











            • @Galik Certainly the appropriate use case should use the appropriate pointer type. There is zero evidence in the OP's code that the instances will be unique, and shared will work in both cases. If they indeed are unique, then the only reason to use a smart pointer at all (as opposed to concrete objects) is for polymorphic reasons (which there is likewise, zero evidence is required, but is an important unknown). Regardless, the concept is the same.

              – WhozCraig
              Nov 15 '18 at 17:00
















            Personally I would want to recommend std::unique_ptr over std::shared_ptr as std::shared_ptrs come with their own set of problems and should only be used when actual shared ownership is required (two or more objects need to reference the same object and it is impossible to know which will die last).

            – Galik
            Nov 15 '18 at 16:25





            Personally I would want to recommend std::unique_ptr over std::shared_ptr as std::shared_ptrs come with their own set of problems and should only be used when actual shared ownership is required (two or more objects need to reference the same object and it is impossible to know which will die last).

            – Galik
            Nov 15 '18 at 16:25













            @Galik Certainly the appropriate use case should use the appropriate pointer type. There is zero evidence in the OP's code that the instances will be unique, and shared will work in both cases. If they indeed are unique, then the only reason to use a smart pointer at all (as opposed to concrete objects) is for polymorphic reasons (which there is likewise, zero evidence is required, but is an important unknown). Regardless, the concept is the same.

            – WhozCraig
            Nov 15 '18 at 17:00





            @Galik Certainly the appropriate use case should use the appropriate pointer type. There is zero evidence in the OP's code that the instances will be unique, and shared will work in both cases. If they indeed are unique, then the only reason to use a smart pointer at all (as opposed to concrete objects) is for polymorphic reasons (which there is likewise, zero evidence is required, but is an important unknown). Regardless, the concept is the same.

            – WhozCraig
            Nov 15 '18 at 17:00











            -1














            Of course, you must deleting Bullets by yourself by delete. But your deletion cycle is not correct.



            To delete values from vector with some condition, use something like this:



            auto condFunc = (const Bullet* x)

            bool rez = (x->getDuration() == 0);
            if(rez)
            delete x;
            return rez;
            ;
            bulletVector.erase(std::remove_if(bulletVector.begin(), bulletVector.end(), condFunc), bulletVector.end());





            share|improve this answer

























            • Your example code doesn't delete the pointees either though, despite being a nicer way to erase them from the vector.

              – Pete Kirkham
              Nov 15 '18 at 14:13











            • @PeteKirkham this example was "To delete values from vector", not to free memory

              – snake_style
              Nov 15 '18 at 14:25











            • In that case it doesn't answer the question, which was about both removing them from the vector and deleting them from the heap. In C++ there is no such thing as 'deleting values from a vector' as 'delete' has a very specific meaning.

              – Pete Kirkham
              Nov 15 '18 at 14:34















            -1














            Of course, you must deleting Bullets by yourself by delete. But your deletion cycle is not correct.



            To delete values from vector with some condition, use something like this:



            auto condFunc = (const Bullet* x)

            bool rez = (x->getDuration() == 0);
            if(rez)
            delete x;
            return rez;
            ;
            bulletVector.erase(std::remove_if(bulletVector.begin(), bulletVector.end(), condFunc), bulletVector.end());





            share|improve this answer

























            • Your example code doesn't delete the pointees either though, despite being a nicer way to erase them from the vector.

              – Pete Kirkham
              Nov 15 '18 at 14:13











            • @PeteKirkham this example was "To delete values from vector", not to free memory

              – snake_style
              Nov 15 '18 at 14:25











            • In that case it doesn't answer the question, which was about both removing them from the vector and deleting them from the heap. In C++ there is no such thing as 'deleting values from a vector' as 'delete' has a very specific meaning.

              – Pete Kirkham
              Nov 15 '18 at 14:34













            -1












            -1








            -1







            Of course, you must deleting Bullets by yourself by delete. But your deletion cycle is not correct.



            To delete values from vector with some condition, use something like this:



            auto condFunc = (const Bullet* x)

            bool rez = (x->getDuration() == 0);
            if(rez)
            delete x;
            return rez;
            ;
            bulletVector.erase(std::remove_if(bulletVector.begin(), bulletVector.end(), condFunc), bulletVector.end());





            share|improve this answer















            Of course, you must deleting Bullets by yourself by delete. But your deletion cycle is not correct.



            To delete values from vector with some condition, use something like this:



            auto condFunc = (const Bullet* x)

            bool rez = (x->getDuration() == 0);
            if(rez)
            delete x;
            return rez;
            ;
            bulletVector.erase(std::remove_if(bulletVector.begin(), bulletVector.end(), condFunc), bulletVector.end());






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 15 '18 at 14:23

























            answered Nov 15 '18 at 13:56









            snake_stylesnake_style

            1,170410




            1,170410












            • Your example code doesn't delete the pointees either though, despite being a nicer way to erase them from the vector.

              – Pete Kirkham
              Nov 15 '18 at 14:13











            • @PeteKirkham this example was "To delete values from vector", not to free memory

              – snake_style
              Nov 15 '18 at 14:25











            • In that case it doesn't answer the question, which was about both removing them from the vector and deleting them from the heap. In C++ there is no such thing as 'deleting values from a vector' as 'delete' has a very specific meaning.

              – Pete Kirkham
              Nov 15 '18 at 14:34

















            • Your example code doesn't delete the pointees either though, despite being a nicer way to erase them from the vector.

              – Pete Kirkham
              Nov 15 '18 at 14:13











            • @PeteKirkham this example was "To delete values from vector", not to free memory

              – snake_style
              Nov 15 '18 at 14:25











            • In that case it doesn't answer the question, which was about both removing them from the vector and deleting them from the heap. In C++ there is no such thing as 'deleting values from a vector' as 'delete' has a very specific meaning.

              – Pete Kirkham
              Nov 15 '18 at 14:34
















            Your example code doesn't delete the pointees either though, despite being a nicer way to erase them from the vector.

            – Pete Kirkham
            Nov 15 '18 at 14:13





            Your example code doesn't delete the pointees either though, despite being a nicer way to erase them from the vector.

            – Pete Kirkham
            Nov 15 '18 at 14:13













            @PeteKirkham this example was "To delete values from vector", not to free memory

            – snake_style
            Nov 15 '18 at 14:25





            @PeteKirkham this example was "To delete values from vector", not to free memory

            – snake_style
            Nov 15 '18 at 14:25













            In that case it doesn't answer the question, which was about both removing them from the vector and deleting them from the heap. In C++ there is no such thing as 'deleting values from a vector' as 'delete' has a very specific meaning.

            – Pete Kirkham
            Nov 15 '18 at 14:34





            In that case it doesn't answer the question, which was about both removing them from the vector and deleting them from the heap. In C++ there is no such thing as 'deleting values from a vector' as 'delete' has a very specific meaning.

            – Pete Kirkham
            Nov 15 '18 at 14:34

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53320959%2fmemory-leaks-in-a-pointer-vector%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            政党

            天津地下鉄3号線