C ++ прохождение указателей - PullRequest
0 голосов
/ 10 августа 2011

Я ожидаю, что приведенный ниже код напечатает 1, но он печатает большое числоЯ не понимаю, почему это происходит, пожалуйста, сообщите.

#include <iostream>
using namespace std;

int * returnArray()
{
    int myArray[5]={1,2,3,4,5};
    return myArray;
}

void printArray(int * myArray)
{
    cout << *myArray<< endl;
}

int main()
{
    printArray(returnArray());
}

Ответы [ 6 ]

5 голосов
/ 10 августа 2011

В вашем коде returnArray возвращает указатель на первый элемент myArray, который является локальным для функции. Когда функция возвращается, память ее локальных переменных освобождается по мере извлечения стека вызовов, поэтому ее можно использовать для других целей. В этом случае, поскольку после этого вы вызываете printArray, область стека, первоначально занятая returnArray, повторно используется для printArray, поэтому память, которая изначально содержала myArray, теперь имеет непредсказуемый контент.

Как отметил Джеймс Канз, лучший способ достичь желаемого - это использовать std::vector<int> вместо int*, что-то вроде

std::vector<int> returnArray()
{
    int myArray[5] = { 1, 2, 3, 4, 5 };
    std::vector<int> result(myArray, myArray + 5);
    return result
}

И измените другие функции соответственно, чтобы взять вектор. Обратите внимание, что в printArray вам необходим myVector[0] для доступа к первому элементу, поскольку векторы не являются указателями.

2 голосов
/ 10 августа 2011

Поскольку этот код вызывает Неопределенное поведение .
Ваш массив является локальным для функции и разрушается при возврате из функции.
Возвращение указателя или ссылки на локальную переменную в функцииНеопределенное поведение.

Неопределенное поведение означает, что все может случиться, и поведение не может быть объяснено.Программа может работать или не работать, или даже зависать. Невозможно определить результаты.

2 голосов
/ 10 августа 2011

Функция returnArray эффективно возвращает указатель на данные стека, который больше не будет действительным после его возврата. Переменная myArray[5] хранится в стеке. После возврата из функции стек используется для хранения других данных. Таким образом, значение по возвращенному адресу не имеет значащего значения для вызывающей функции.

0 голосов
/ 10 августа 2011

Измените объект массива на постоянный.
то есть. Сделайте это статическим объектом продолжительности хранения. Это означает, что срок его службы будет длиться дольше, чем вызов функции /

int * returnArray()
{
    static int myArray[5]={1,2,3,4,5};
  //^^^^^^  
  // a static in function scope means the variable is a static storage duration
  // object. This means its life span is longer than the application (ie it will
  // be tidied up after main exits).
  //
  // Thus it is perfectly valid to return it as the result from the function.

    return myArray;
}

В вашей версии объект был автоматической переменной.
Это означает, что он прекратил существование после того, как вышел из области видимости (в конце функции).

0 голосов
/ 10 августа 2011

myArray выпадает из области видимости при возврате returnArray.Другими словами, вы возвращаете указатель на данные, которых больше нет.

Существует несколько решений.Вы можете сделать myArray глобальной переменной или динамически распределить ее, как в

int myArray[5] = new int[5];

. Если вы сделаете это, вам придется удалить его, когда он вам больше не нужен, используя оператор типа

delete[] myArray;
0 голосов
/ 10 августа 2011

int myArray [] выходит за рамки видимости, когда вы ссылаетесь на него в функции printArray. Это означает, что указатель * myArray в printArray () указывает на некоторый мусор в стеке, который больше не является допустимым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...