Инициализация указателя в классах - PullRequest
0 голосов
/ 09 февраля 2011

Допустим ли следующий код?

class Foo()
{
    int* Bar;

    public:

    Foo()
    {
        *Bar = 123;
    }
}

Другими словами, действительно ли Bar будет указывать на реальное пространство памяти до того, как значение будет присвоено этому пространству в конструкторе?Или я должен сделать что-то вроде этого:

class Foo()
{
    int* Bar;

    public:

    Foo()
    {
        Bar = new int[1];
        *Bar = 123;
    }

    ~Foo()
    {
        delete[] Bar;
    }
}

Ответы [ 4 ]

2 голосов
/ 09 февраля 2011

Если вам не нужен динамический массив, тогда

Bar = new int;
*Bar = 123;

достаточно! И тогда вы должны сделать это:

delete Bar; //not delete[] Bar;

-

Однако, если вы хотите динамический массив (используя который вы можете хранить несколько значений), сделайте следующее:

Bar = new int[5];
Bar[0] = 123;
Bar[3] = 788; 
//etc

Тогда delete[] Bar - это правильный способ удаления выделенной памяти!

2 голосов
/ 09 февраля 2011

Вы должны назначить память, как вы сделали во втором примере.Если вы попытаетесь запустить код в первом примере, он, скорее всего, завершится с ошибкой нарушения прав доступа, поскольку вы пытаетесь записать целое число 123 в любую часть памяти, на которую указывает значение неинициализированного указателя Bar.

1 голос
/ 10 февраля 2011

В первом примере -

int* Bar;

Указатели указывают на объект.Задача компилятора - назначить память (т. Е. 4 байта) для целочисленного указателя Bar для хранения адреса целочисленной переменной.Однако, местоположение, на которое оно указывает, должно быть указано для разыменования.

Это больше похоже на то, что банк предоставляет вам счет.Наличие банковского счета не означает, что вы можете получать деньги из банкомата.На вашем счету должны быть деньги, чтобы можно было рисовать.Транзакция терпит неудачу, если у вас нет денег и в парадигме программирования поведение не определено.Итак, ваш первый пример поведения не определен.Если моя аналогия слишком неловкая, извините.

Во втором примере -

int* Bar = new int[1] ; // Here [1] is unnecessary as your Bar points to a single integer memory location.

Здесь Bar - указатель, указывающий на местоположение действительного целого числа, полученного из бесплатного магазина,Таким образом, местоположение, на которое указывает Bar, может иметь значения мусора.Итак, инициализируйте его, прежде чем разыменовывать.т. е.

*Bar = 10;
*Bar *= 10;

Во втором примере, поскольку вы управляете ресурсами, вы обязаны вернуть источники обратно в бесплатное хранилище.

1 голос
/ 09 февраля 2011

Будет ли Bar фактически указывать на реальное пространство памяти до того, как ему будет присвоено значение в конструкторе?

Нет.Указатель - это просто «простая» переменная.Это не выделит вам никакой памяти.Кроме того, если вы не инициализируете его, он будет указывать на какое-то произвольное и в основном непредсказуемое место в памяти.

Вообще говоря, вам следует либо инициализировать его на NULL (или 0 в зависимости от предпочтений), либо иным образом.в память, которую вы распределили (как вы делаете с Bar = new int).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...