0

I am playing a bit with raw pointers on c++, I know that nowadays it is good practices to use smart pointers, but as I am learning c++ on my own, I would like first understand raw pointers before moving to smart pointers.

To play around I have created a fakeClass, and playing in a Xcode console project c++:

/** fakeClass.hpp **/
#ifndef fakeClass_hpp
#define fakeClass_hpp

namespace RPO {

    class fakeClass {
    private:
        int _id;

    public:
        fakeClass(int id);
        ~fakeClass();

        void message();
    }; // end class
} // end namespace

#endif

/** fakeClass.cpp **/
#include "fakeClass.hpp"

#include <iostream>

namespace RPO {

    fakeClass::fakeClass(int id) {
        _id = id;
        std::cout << "Creating object: " << _id << std::endl;
    }

    fakeClass::~fakeClass() {
        std::cout << "Destroying objet: " << _id << std::endl;
    }

    void fakeClass::message() {
        std::cout << "Object: " << _id << std::endl;
    }
}

/** main.cpp **/
int main(int argc, const char * argv[]) {
    // Instantiate on the stack
    RPO::fakeClass fClass(1);
    fClass.message();

    // Instantiate on the heap
    RPO::fakeClass *fClassPointer = new RPO::fakeClass(2);
    fClassPointer->message();

    fClassPointer = new RPO::fakeClass(3); // Create new object #3, on non deleted pointer
    fClassPointer->message();

    delete fClassPointer; // Free memory of object #3, but still pointing to the memory address
    fClassPointer = nullptr; // pointer is pointing to null right now

    fClassPointer->message(); // throws an error
}

Output:

Creating object: 1
Object: 1
Creating object: 2
Object: 2
Creating object: 3
Object: 3
Destroying object: 3
Destroying object: 1

Edited:

Thanks to the revisors, I have been searching but could not find anything, but the question posted by tobi303 answers one of my questions (about why one method is still responding after free the memory), but as I said on the title the main question was about leaks.

As it can be seen, object #2 is never destroyed, so it is an obvious memory leak. I breakpointed after creating the object #3, and typed on Console "leaks pruebaC", following instructions from this question, but I get no leak report... why?

leaks Report Version:  2.0
Process 1292: 147 nodes malloced for 17 KB
**Process 1292: 0 leaks for 0 total leaked bytes.**

Also tried after de fClassPointer = nullptr; with the same result.

So, 2 questions, why the leak didn't showed up? and, do the memory used by an app is freed when the app is terminated? (even if it is a memory leak with no pointers)

Thank you.

PS: extra bonus, when I see examples with "char *myString", should I "delete myString" after?

raululm
  • 105
  • 1
  • 1
  • 10
  • 3
    `fClassPointer2->message(); // what could happen?` Undefined behaviour. – n. m. could be an AI Jul 12 '17 at 14:33
  • Just a note: it's better using an initialization list in your constructor `fakeClass::fakeClass(int id)` – Marco Luzzara Jul 12 '17 at 14:41
  • Calling `delete` or `free` doesn't necessarily erase the data from that memory location immediately, but rather it is marking that memory location as writable. – Thomas Phan Jul 12 '17 at 14:48
  • @Thomas Phan This is a very dangerous assumption to be making. It might work like this some of the time, but expecting things to behave this way is simply wrong. –  Jul 12 '17 at 15:00
  • PS. Extra bonus answer: Almost certainly no. `delete[] myString;` is a bit more likely, but nowhere near certain. But really, the only place where `char* myString` should occur is somehere in the bowels of `std::string`, and `std::string::~string` handles cleanup. – MSalters Jul 12 '17 at 15:02
  • @Frank Well my intention wasn't to tell the OP that it's a good thing to try to access data at a memory address after calling `free` or `delete`, but to simply offer an explanation of why OP was still able to access that data instead of getting garbage data or crashing. – Thomas Phan Jul 12 '17 at 19:34
  • @Thomas Phan From a C++ standpoint, really, there is no other explanation than "dumb luck". This is not an assembly question. –  Jul 12 '17 at 19:38

1 Answers1

1

That is my question, I suppose is because memory is freed, but not yet overwritten, and that is why I get the "Object: 2" message after deleting the object #2. Is that correct?

This is "correct" in the sense that most implementations will behave this way, but your situation qualifies as "undefined behavior", so there is no guarantee that this will work accross different compilers, compiler versions, or architectures.

when running on Terminal "leaks pruebaC", I get no leak report... why?

There is no leak detector added by default, because it adds unnecessary weight to the program (makes it slow to shut down). You have to add a leak detector explicitely by yourself (like linking to tcmalloc).

when I see examples with "char *myString", should I "delete myString" after?

Here's a rule of thumb for this: Every new needs to be matched with a delete, and vice-versa.