Pointer Указатель Методы C ++ - PullRequest
0 голосов
/ 26 ноября 2008

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

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

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

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

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

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

Ответы [ 6 ]

5 голосов
/ 26 ноября 2008

Как я могу сделать массив, который указывает к объектам?

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

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

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

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

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

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

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

2 голосов
/ 26 ноября 2008

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

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 и т. Д.

1 голос
/ 26 ноября 2008
int **myName;

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

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

  return array;
}
1 голос
/ 26 ноября 2008

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

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

int **getStuff() {
    return myName;       // 1
    return &myName[0];   // 2
}
0 голосов
/ 07 августа 2012

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

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;
    }
0 голосов
/ 26 ноября 2008

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

int **myFunction() {
    int **myArray = new int*[5];
    return myArray;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...