Dynami c массив указателей, как это сделать правильно? - PullRequest
0 голосов
/ 23 апреля 2020

Я знаю, я мог бы использовать std :: vector или что-то в этом роде, но я хочу знать, где я ошибаюсь. В приведенном ниже примере, только p3 в моих глазах действительно указатель на массив указателей и используется так, как я ожидал. Использование p1 вместо этого выглядит как-то неправильно для меня, потому что похоже, что p1 также является массивом указателей, таких как p2, а не указателем на массив указателей, за исключением операции удаления. Поэтому, когда я пытаюсь использовать p2, как я использую p3:

(*p2)[i] = new Foo(i);

, возникает ошибка:

ambiguous overload for ‘operator=’ (operand types are ‘Foo’ and ‘Foo*’)

Вопрос :

  1. Почему я должен использовать приведение в строке, где выделен p3?
  2. Это назначение для p3 правильное или оно просто работает по инциденту?
#include <iostream>

using namespace std;

class Foo
{
 public:
   Foo (int key)
      : key(key)
   {}

   int show() const
   {
      return key;
   }

 private:
   int key;
};

int main (int, char**)
{
   int aSize = 10;
   using FooP = Foo *;

   FooP *p1 = new FooP[aSize];
   FooP p2[aSize];
   FooP (*p3)[] = (FooP (*)[]) new FooP[aSize];

   for (int i=0; i < aSize; i++)
   {
      p1[i] = new Foo(i);
      p2[i] = new Foo(i + aSize);
      (*p3)[i] = new Foo(i + aSize * 2);
   }

   for (int i=0; i < aSize; i++)
   {
      cout << p1[i]->show() << ", "
           << p2[i]->show() << ", "
           << (*p3)[i]->show()
           << endl;

      delete p1[i];
      delete p2[i];
      delete (*p3)[i];
   }
   cout << endl;

   delete [] p1;
   delete [] p3;


   return 0;
}


1 Ответ

0 голосов
/ 24 апреля 2020

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

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

Благодаря @ exprosi c за полезную подсказку в комментарии к https://en.cppreference.com/w/cpp/language/new

Цитата оттуда:

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

...