-3

My code pass the compiler, but I have a question about the concept of the pointer.

main.cpp:

int main(int argc, const char * argv[])
{
    int inputPuzzle[3][3];

    std::cout << "Set the puzzle: " << "\n";
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            std::cin >> inputPuzzle[i][j];
        }
    }

    puzzle puzzle_1 = *new puzzle(inputPuzzle);
    puzzle_1.display();

    return 0;
}

puzzle.h:

class puzzle
{
    public:
        puzzle();
        puzzle(int [][maxCol]);
        ~puzzle();
    public:
        int puzz [maxRow][maxCol];
};

puzzle.cpp:

puzzle::puzzle(int a[][maxCol])
{
    for (int i = 0; i < maxRow; i++) {
        for (int j = 0; j < maxCol; j++) {
            puzz[i][j] = a[i][j];
        }
    }
}

My question is about the statement :puzzle puzzle_1 = *new puzzle(inputPuzzle);

Why do I have to add "*" in front of the new object in which I want to assign a 2D array ?

Christos
  • 53,228
  • 8
  • 76
  • 108
user3097464
  • 7
  • 1
  • 4
  • Hello-o instant memory leak. Please, [read a book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) on C++ to get the full deal on how to use pointers. This kind of thing has [been asked before](http://stackoverflow.com/questions/5727/what-are-the-barriers-to-understanding-pointers-and-what-can-be-done-to-overcome), but nowadays general conceptual questions about how to use pointers is frowned on. – The Forest And The Trees Apr 01 '14 at 14:57
  • Because the code is bad and wrong ;) – Lightness Races in Orbit Apr 01 '14 at 15:05
  • Possible duplicate of https://www.youtube.com/watch?v=i49_SNt4yfk (by the way, this has nothing to do with your 2D array). – Jason C Apr 01 '14 at 15:18
  • 1
    Ooh, `*new`, the memory leak operator, we meet again. – R. Martinho Fernandes Apr 01 '14 at 15:20
  • @presiuslitelsnoflek Thanks for your help for giving me the direction! – user3097464 Apr 01 '14 at 21:51
  • @TheForestAndTheTrees Great book list! Thank you! – user3097464 Apr 01 '14 at 21:53
  • @LightnessRacesinOrbit That's why I have the question on that statement. The Xcode suggests me to do so, and I do not know the reason. it passed the compiler.....in a strange way.. – user3097464 Apr 01 '14 at 21:56
  • @R.MartinhoFernandes That is called memory leak operator? I got a new lesson! – user3097464 Apr 01 '14 at 22:00
  • Compilers can tell you the quickest/nearest fix to make your code compile. They rarely know enough to read your mind and tell you how you _should_ write your program, though. They certainly don't detect memory leaks, or advise you against needless manual memory management. That's what _we're_ for (apparently)! – Lightness Races in Orbit Apr 01 '14 at 22:22

2 Answers2

4

You're programming C++, where new returns a pointer. When you use the asterisk it's the dereference operator, and basically turns a pointer into a non-pointer.

Using the dereference operator like that means that you actually lose the pointer created by new, and you can not free that allocated memory with delete which, of course, leads to a memory-leak.

To avoid losing the pointer, you have to declare the variable as a pointer:

puzzle* puzzle_1 = new puzzle(inputPuzzle);

Then you have to use the pointer member selector operator instead when accessing members:

puzzle_1->display();

And, to avoid leaking memory, when you're done with the pointer you must delete it:

delete puzzle_1;

However, in C++ there is seldom any need to use pointers; instead just declare it as a normal variable:

puzzle puzzle_1(inputPuzzle);
puzzle_1.display();

Unrelated to your question, but if maxRow or maxCol is larger than 3, then you will read from outside the memory for the array inputPuzzle. This will lead to undefined behavior.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    or if you need (as in actually need, not just want) you should use smart pointers to take care of *most* of the handling. There are times though when you really do need to delve into the muddy waters of 'raw pointers', always favour cooking your pointers if you can, with a nice bit of pepper corn source and fried mushRAMs. – thecoshman Apr 01 '14 at 15:20
2

The most important part here is the new keyword. It returns a pointer to the newly instantiated object. Check the Dynamic memory allocation for more information and to understand when and how to use pointers, and how the new keyword works.

Now, we know that the new keyword returns a pointer, and you want to obtain an object not a pointer, hence you have to dereference your pointer.

Two correct solutions now:

// without pointers
puzzle puzzle_1(inputPuzzle); // initialize the object without going through a copy 
puzzle_1.display();

// with pointers
puzzle *puzzle_1 = new puzzle(inputPuzzle);
puzzle_1->display(); //notice that we used -> here as it's a pointer
// do stuffs here
delete puzzle_1; // free the memory
zeapo
  • 103
  • 2
  • 7