2010-04-15 3 views
3

Я пытаюсь вернуть простой массив, но я не получаю правильный результат. Я получаю следующееArray не возвращается правильно

arr1[0] = 1 
arr1[1] = 32767 

результат, а результат должен был

arr1[0] = 1 
    arr1[1] = 15 

Просьба предложить.

int *sum(int a, int b){ 
    int arr[2]; 
    int *a1; 
    int result = a+b; 
    arr[0]= 1; 
    arr[1]= result; 
    a1 = arr; 
    return a1; 
} 
int main(){ 

    int *arr1 = sum(5,10); 
    cout<<"arr1[0] = "<<arr1[0]<<endl; 
    cout<<"arr1[1] = "<<arr1[1]<<endl; 

    return 0; 

} 
+6

Поскольку вы отметили это как C++, рассмотрели ли вы использование std :: vector? Ваш код немного запутан, и его можно было бы упростить, довольно хорошо переходя на этот маршрут. – andand

ответ

7

Попробуйте это ...


#include <vector> 
#include <iostream> 

std::vector<int> sum(int a, int b) 
{ 
    std::vector<int> rv(2); 
    rv[0]= 1; 
    rv[1]= a+b; 
    return rv; 
} 

int main() 
{ 
    std::vector<int> arr1 = sum(5,10); 
    std::cout << "arr1[0] = " << arr1[0] << std::endl; 
    std::cout << "arr1[1] = " << arr1[1] << std::endl; 

    return 0; 
} 

5

a1 - локальная переменная, выделенная память на стеке. Если вы хотите вернуть int *, вы должны выделить память в куче.

int *arr = (int *)malloc(sizeof(int) * 2)); 

//CAUTION you need to de-allocate memory [read about free()] 

Объяснение:

См arr на самом деле массив до тех пор, пока функция int *sum(int, int) не завершена. ТАК, то, что вы возвращаете, на самом деле является адресом, где arrдействительно был, и его уже нет.

Когда вы пытаетесь получить доступ к , что ячейку памяти в main(), вы просто получите мусора/случайные значения.

+3

Помните, что вызывающему абоненту необходимо удалить массив или родиться новая утечка памяти. –

+0

IMO Я думаю, что OP совершенно новый для C/C++, не может объяснить ему все детали в одном сообщении :). –

+0

'Когда вы пытаетесь получить доступ к этой ячейке памяти в main(), вы просто получаете мусор/случайные значения. . Вы получаете неопределенное поведение, а значения мусора - это не самое худшее, что может случиться. –

16

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

Вы можете передать указатель на массив, чтобы массив был изменен функцией.

Кроме того, вы можете вернуть копию массива, если она завернута внутри структуры/класса, например std::tr1::array (или boost::array).

+1

Есть, конечно, возможность возврата указателя на массив, выделенный для кучи. Затем вызывающий абонент будет отвечать за его удаление. –

+1

Да, вы можете, как сказал Sapce_C0wb0y, но это действительно плохая практика, потому что пользователь вашей функции в большинстве случаев не будет читать вашу политику, чтобы освободить память, и она просочится. –

+0

. Вы могли бы усложнить пользователю возможность испортить возвращая умный указатель, но он должен быть тем, который правильно обрабатывает массивы (использует delete []). Boost имеет shared_array для таких вещей. Но я бы скорее использовал векторный или другой стандартный контейнер. –

0

Неправильно возвращать указатель на локально определенный массив. a1 помещается в стек, который очищается, когда функция возвращается. Поэтому вам больше не разрешается обращаться к этой памяти.

Чтобы «вернуть массив», вы можете динамически выделить его с помощью new, а затем вернуть его. Имейте в виду, что это заставит вас освободить его позже, поэтому вам придется тщательно разработать политику управления памятью для этого массива.

1

очень плохой. int arr[2]; является локальной переменной и живет в стеке. вы не можете возвращать указатели на стек из функции. они становятся недействительными.

0

arr находится на стеке - как только вы вернетесь с sum(), его больше не существует. Указатель на него может возвращать случайные данные, что вы видите, когда возвращаете a1.

1

Хм .. ну, arr - переменная стека, и вы возвращаете указатель на нее и ожидаете ее сохранения.

0

Вы должны сначала выделить память для arr, поэтому она не является переменной стека. Тогда кто-то вне вашей функции должен освободить его.Лучше, если вы передадите arr в качестве параметра функции, поэтому вы можете выделить и освободить память для него на одном и том же уровне абстракции.

5

Вы возвращаете указатель на локальную переменную - когда sum() вернулся в main(), массив больше не существует.

Вы не можете даже возвращать массив по значению, если вы не обернуть их, но вы могли бы просто вернуть стандартный контейнер как std::vector или std::pair:

std::pair<int,int> f(int a, int b) { 
    return std::make_pair(1, a+b); 
} 

int main() { 
    std::pair<int,int> res = f(5,10); 
    std::cout << res.first << ", " << res.second << std::endl; 
} 
Смежные вопросы