У меня два вопроса:
1) Как создать массив, указывающий на объекты целых чисел?
int* myName[5]; // is this correct?
2) Если я хочу вернуть указатель на массив, который указывает на объекты (например, (1)), как я могу сделать это в методе? т.е.) Я хочу реализовать метод:
int **getStuff() {
// what goes here?
return *(myName); // im pretty sure this is not correct
}
Спасибо за помощь!





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;.
Проголосовали за, но помните, что нельзя возвращать указатели на вещи, которые не гарантированно работают после возврата из функции (то есть локальные объекты, живущие в стеке).
1) Правильно - это массив из 5 указателей на ints
2) Вы можете вернуть указатель на массив указателей на int, вернув указатель на первый элемент этого массива. У этого есть два уровня косвенности, поэтому вам понадобятся две звездочки. Вы также можете вернуть массив обычным образом, поскольку массивы автоматически распадаются на указатели на свои первые элементы.
int **getStuff() {
return myName; // 1
return &myName[0]; // 2
}
Проголосовали за, но помните, что нельзя возвращать указатели на вещи, которые не гарантированно работают после возврата из функции (то есть локальные объекты, живущие в стеке).
int **myName;
int **getStuff() {
int **array = new int*[5];
for (int i = 0; i < 5; i++)
{
int key = i;
array[i] = &key;
}
return array;
}
Проголосовали за, но помните, что нельзя возвращать указатели на вещи, которые не гарантированно работают после возврата из функции (то есть локальные объекты, живущие в стеке).
Обратите внимание, что ваш код,
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;
}
Ваш вопрос действительно вопрос C. Если вы действительно хотите писать на C++, просто используйте класс std :: vector для своих массивов. Это 21 век.