2014-04-01 4 views
-3

Мой код передает компилятор, но у меня есть вопрос о концепции указателя.C++ назначить 2D-массив объекту

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]; 
     } 
    } 
} 

Мой вопрос об утверждении: puzzle puzzle_1 = *new puzzle(inputPuzzle);

Почему мне нужно добавить «*» в перед новым объектом, в котором я хочу назначить 2D-массив?

+0

Привет-о течи мгновенной памяти. Пожалуйста, прочитайте книгу (http: // stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) на C++, чтобы получить полную информацию о том, как использовать указатели. Такие вещи были [заданы до] (http://stackoverflow.com/questions/5727/what-are-the-barriers-to-understanding-pointers-and-what-can-be-done-to-overcome), но в настоящее время общие концептуальные вопросы о том, как использовать указатели, неодобрились. –

+0

Потому что код плохой и неправильный;) –

+0

Возможный дубликат https://www.youtube.com/watch?v=i49_SNt4yfk (кстати, это не имеет ничего общего с вашим 2D-массивом). –

ответ

4

Вы программируете C++, где new возвращает указатель. Когда вы используете звездочку, это оператор разыменования и в основном превращает указатель в не указатель.

Используя оператор разыменования, как это означает, что вы на самом деле потерять указатель, созданный new, и вы не можете бесплатно, что выделенную память с delete, которые, конечно же, приводит к памяти утечек.

Чтобы избежать потерь указателя, вы должны объявить переменную как указатель:

puzzle* puzzle_1 = new puzzle(inputPuzzle); 

Тогда вы должны использовать оператор выбора члена указателя вместо при доступе пользователей:

puzzle_1->display(); 

И , чтобы избежать утечки памяти, когда вы закончите с указателем, вы должны: delete:

delete puzzle_1; 

Однако в C++ редко нужно использовать указатели; вместо того, чтобы просто объявить его как обычную переменную:

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

неродственных на ваш вопрос, но если maxRow или maxCol больше 3, то вы будете читать из-за пределов памяти для массива inputPuzzle. Это приведет к undefined behavior.

+1

, или если вам нужно (как на самом деле нужно, а не просто хотеть), вы должны использовать интеллектуальные указатели, чтобы позаботиться о * большинстве * обработки. Бывают моменты, когда вам действительно нужно вникать в грязные воды «сырых указателей», всегда предпочитайте приготовить свои указатели, если сможете, с приятным кусочком перца и кукурузными мошенниками. – thecoshman

2

Важнейшей частью является ключевое слово new. Он возвращает указатель к вновь создаваемому объекту. Проверьте Dynamic memory allocation для получения дополнительной информации и для понимания того, когда и как использовать указатели, и как работает ключевое слово new.

Теперь мы знаем, что ключевое слово new возвращает указатель, и вы хотите получить объект, а не указатель, поэтому вы должны разыменовать свой указатель.

Два правильных решения сейчас:

// 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 
+1

'puzzle puzzle_1 (inputPuzzle);' достаточно. –

+0

Действительно, просто использовал свой собственный код, чтобы он не нарушил изменения. – zeapo

+3

Изменение именно то, что ему нужно! :) –

Смежные вопросы