Методы указателя указателя C++

У меня два вопроса:

1) Как создать массив, указывающий на объекты целых чисел?

int* myName[5];  // is this correct?

2) Если я хочу вернуть указатель на массив, который указывает на объекты (например, (1)), как я могу сделать это в методе? т.е.) Я хочу реализовать метод:

int **getStuff() {
// what goes here?
return *(myName); // im pretty sure this is not correct
}

Спасибо за помощь!

Ваш вопрос действительно вопрос C. Если вы действительно хотите писать на C++, просто используйте класс std :: vector для своих массивов. Это 21 век.

Jim In Texas 26.11.2008 09:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
1 379
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

How can I make an array which points to objects?

int * myName[5]; /* correct */

If I want to return a pointer to an array, which points to objects (like (1)) how can I do this in a method?

Технически вы пишете эту функцию:

int * (* getStuff() )[5] {
    return &myName;
}

Это возвращает указатель на этот массив. Однако вы не хотите этого делать. Вы хотели вернуть указатель на первый элемент массива:

int ** getStuff() {
    return myName; /* or return &myName[0]; */
}

Таким образом, теперь вы можете получить доступ к элементам по своему усмотрению, например getStuff()[0] = &someInteger;.

Проголосовали за, но помните, что нельзя возвращать указатели на вещи, которые не гарантированно работают после возврата из функции (то есть локальные объекты, живущие в стеке).

Max Lybbert 26.11.2008 04:01

1) Правильно - это массив из 5 указателей на ints

2) Вы можете вернуть указатель на массив указателей на int, вернув указатель на первый элемент этого массива. У этого есть два уровня косвенности, поэтому вам понадобятся две звездочки. Вы также можете вернуть массив обычным образом, поскольку массивы автоматически распадаются на указатели на свои первые элементы.

int **getStuff() {
    return myName;       // 1
    return &myName[0];   // 2
}

Проголосовали за, но помните, что нельзя возвращать указатели на вещи, которые не гарантированно работают после возврата из функции (то есть локальные объекты, живущие в стеке).

Max Lybbert 26.11.2008 04:03
int **myName;

int **getStuff() {
  int **array = new int*[5];

  for (int i = 0; i < 5; i++)
  {
    int key = i;
    array[i] = &key;
  }

  return array;
}

Проголосовали за, но помните, что нельзя возвращать указатели на вещи, которые не гарантированно работают после возврата из функции (то есть локальные объекты, живущие в стеке).

Max Lybbert 26.11.2008 04:04

Обратите внимание, что ваш код,

int* myName[5];

объявляет массив, содержащий 5 значений, каждое из которых является «указателем на int», о чем вы и просили.

Однако это C++, вот и все, что он делает. Как разработчику сценария Python это может преподнести вам сюрпризы.

Он не дает ни одному из этих 5 указателей разумных значений и не создает никаких целых чисел, на которые они могли бы указывать.

Если вы поместите его в тело функции, он создаст массив в стеке. Это означает, что массив перестанет существовать, когда закончится текущая область видимости (что, проще говоря, означает, что вы перейдете к закрывающему закрытому фигурному объекту, поэтому, например, это делает return). Так, в частности, плохой следующий код:

int **myFunction() {
    int *myArray[5];
    return myArray;
} // <-- end of scope, and return takes us out of it

Он может скомпилироваться, но функция возвращает указатель на то, чего больше не существует к тому моменту, когда вызывающий его видит. Это приводит к тому, что мы называем «неопределенным поведением».

Если вы хотите, чтобы массив существовал вне функции, в которой он был создан, вы можете создавать его в куче каждый раз, когда вызывается ваша функция, и возвращать указатель, например:

int **myFunction() {
    int **myArray = new int[5];
    return myArray;
}

При каждом вызове функция возвращает другой массив. Когда вызывающий абонент закончил с ним, он должен уничтожить массив, например:

delete[] myArray;

в противном случае он никогда не будет освобожден и будет сидеть без дела, используя память навсегда (или когда ваша программа завершится в большинстве ОС).

В качестве альтернативы вы можете использовать ключевое слово static для создания массива с «глобальной продолжительностью хранения» (это означает, что он существует, пока выполняется программа, но каждый раз есть только один из них, а не новый). Это означает, что функция при каждом вызове возвращает один и тот же массив. Вызывающий может сохранить в нем несколько указателей, забыть об этом, снова вызвать функцию и увидеть те же указатели, которые остались там:

int **myFunction() {
    static int *myArray[5];
    return myArray;
}

Обратите внимание, насколько этот код похож на очень плохой код из более раннего.

Наконец, если вы просто хотите создать массив целых чисел, а не массив указателей на целые числа, вы можете сделать это:

int myArray[5] = { 1, 2, 3, 4, 5};

Фактически это создает 5 целых чисел (что означает, что он назначает пространство, в котором могут храниться сами целые значения. Это отличается от массива указателей, в котором хранятся адреса пространства, используемого для хранения целочисленных значений).

Он также сохраняет указанные значения в этом пространстве: myArray [0] теперь равно 1, myArray [1] равно 2 и т. д.

Стив Джессоп, я думаю, вы имели в виду:

int **myFunction() {
    int **myArray = new int*[5];
    return myArray;
}

Это возвращает указатель массива кучи (не указатель на его элементы), который можно проверить и удалить. Ничего не протекает.

template <class T>
T* newarray(int len)
    {
        T *a;
        try
           {
               a = new T[len];
               memset(a,0,len*sizeof(T));
               return a;
           }
        catch (...)         
           {return 0;}
    }   

. . .

void foo()
    {
        float *f=0;
        f=newarray<float>(1000000);
        if (!f) return;
        //use f
        delete [] f;
    }

Другие вопросы по теме