Если `new int` возвращает` int * `, то почему` new int [n] `не возвращает` int ** `? - PullRequest
2 голосов
/ 11 июля 2020

Меня озадачивает, как и new int, и new int[n] возвращают int*. Почему последний не возвращает int**?

Вот некоторый контекст: обратитесь к переменной data ниже во фрагменте из Goodrich, Tamassia и Mount's 2nd ed. Структуры данных и алгоритмы в учебнике C ++:

class Vect {
   public:
      Vect(int n);
       ~Vect();
      // ... other public members omitted
   private:
      int* data;
      int size;
};
    
Vect::Vect(int n) {
    size = n;
    data = new int[n];
}
    
Vect::~Vect() {
    delete [] data;
}

Ответы [ 2 ]

5 голосов
/ 11 июля 2020

(ответы содержат упрощения для пояснений)

В C указатель на массив целых чисел будет иметь тип int**, если я Я не ошибаюсь.

Вы ошибаетесь. В C это также будет int*.

Когда вы объявляете: int foo[] = { 1, 2, 3 }, имя массива (foo) может рассматриваться как указатель на его первый элемент (1). Указатель на int равен int*.

Кроме того, почему мы вызываем delete[] вместо delete, чтобы удалить int* (данные)?

delete удаляет отдельный объект. delete [] удаляет динамический c массив.

1 голос
/ 11 июля 2020

new int[n] не может вернуть результат типа int**, потому что значение int** должно указывать на объект типа int* (объект-указатель).

new int[n] выделяет память для массива n объектов, каждый из которых имеет тип int. Он не создает объект-указатель.

Возвращаемое значение int* указывает на начальный (0-й) элемент выделенного массива. Доступ к другим элементам массива можно получить с помощью арифметики указателя c.

Это могло быть было определено для получения результата типа int (*)[n], который является указателем на массив n int элементов, за исключением того, что (а) C ++ не допускает массивы с непостоянными границами, и (б) даже для чего-то вроде int (*)[4] это менее удобно, чем int*.

C ++, как и язык его предков C, рассматривает массивы как граждан второго сорта. Выражения массива в большинстве, но не во всех контекстах "преобразуются" (корректируются во время компиляции) в выражения указателя, указывающие на начальный элемент объекта массива, а доступ к элементам массива осуществляется с помощью арифметики указателя c. (Оператор индексации a[i] - это синтаксис c сахар для *(a+i)).

Да, все это может сбивать с толку и противоречить интуиции.

Рекомендуемая литература: Раздел 6 comp.lang. c FAQ (большая часть относится как к C, так и к C ++).

...