Передать массив из функции
От: Аноним  
Дата: 29.06.10 12:11
Оценка: :))) :))
Привет, необходимо передать массив заданный в функции:
int* myfunc(int *b)
{
int i;
long a[200];

for (i=0;i<200;i++)
a[i]=b[i];
return a;
}
Подскажите, почему возвращаются только первые несколько элементов, как исправить? Заранее спасибо.
Re: Передать массив из функции
От: dabeat_bf Украина http://alexmogurenko.com
Дата: 29.06.10 12:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Привет, необходимо передать массив заданный в функции:

А>int* myfunc(int *b)
А>{
А>int i;
А>long a[200];

А>for (i=0;i<200;i++)

А>a[i]=b[i];
А>return a;
А>}
А>Подскажите, почему возвращаются только первые несколько элементов, как исправить? Заранее спасибо.

вообще не особо хорошо чтоб функция возвращала указатель, но если очень хочеться, то:


int * a = new int[200];


P.S. не забудьте вызвать
delete []

для результата функции или получите лик
Re: Передать массив из функции
От: Анатолий Широков СССР  
Дата: 29.06.10 12:22
Оценка: +3

int* myfunc(int *dst, int *src, size_t s)
{
   for(size_t i = 0; i < s; i++)
      dst[i] = src[i];
   return dst;
}

...
int a[200];
int b[200];
myfunc(b, a, s);
Re: Передать массив из функции
От: stapter  
Дата: 29.06.10 13:07
Оценка: 1 (1)
Здравствуйте, Аноним, Вы писали:

А>Привет, необходимо передать массив заданный в функции:

А>int* myfunc(int *b)
А>{
А>int i;
А>long a[200];

А>for (i=0;i<200;i++)

А>a[i]=b[i];
А>return a;
А>}
А>Подскажите, почему возвращаются только первые несколько элементов, как исправить? Заранее спасибо.

Тебе вообще повезло, что программа не завершилась аварийно
Так делать нельзя. Потому что массив "a", выделен на стеке. А что происходит со стеком функции, при выходе из функции? Правильно! Он освобождается, и, таким образом, ты возвращаешь невалидный указатель. Как вариант можешь выделить память в куче, и не забыть ее освободить, чтобы не было утечек. А можешь просто передать указатель на выделенную память, куда ты потом скопируешь массив, как это было продемонстрировано выше.
Re: Передать массив из функции
От: Cris Украина  
Дата: 29.06.10 13:47
Оценка: +1 -3 :)
Здравствуйте, Аноним, Вы писали:

А>Привет, необходимо передать массив заданный в функции:

А>int* myfunc(int *b)
А>{
А>int i;
А>long a[200];

А>for (i=0;i<200;i++)

А>a[i]=b[i];
А>return a;
А>}
А>Подскажите, почему возвращаются только первые несколько элементов, как исправить? Заранее спасибо.
попробуй в функции обьявить массив a как
static long a[200];

он должен оставить массив после завершения функции
Re[2]: Передать массив из функции
От: monax  
Дата: 29.06.10 14:18
Оценка: 1 (1) -1
Здравствуйте, Cris, Вы писали:

C>он должен оставить массив после завершения функции


Нельзя так делать, это глобальная переменная получится.

#include <iostream>

using namespace std;

int* foo() {
    static int a[3];
    for (int i = 0; i < 3; i++) {
        a[i] = i;
    }

    return a;
}

int main() {
    int *a;
    int *b;

    a = foo();

    cout << a[0] << ' ' << a[1] << ' ' << a[2] << endl;

    b = foo();
    cout << b[0] << ' ' << b[1] << ' ' << b[2] << endl;

    a[1] = 100;

    cout << a[0] << ' ' << a[1] << ' ' << a[2] << endl;
    cout << b[0] << ' ' << b[1] << ' ' << b[2] << endl;


    return 0;
}


0 1 2
0
1 2
0 100 2

0 100 2


После такого создания массив нужно копировать. Проще сразу создавать его в выделенной для него памяти и возвращать на него указатель, как предложили выше.
Re[3]: Передать массив из функции
От: dabeat_bf Украина http://alexmogurenko.com
Дата: 29.06.10 14:41
Оценка:
Здравствуйте, monax, Вы писали:
M>Нельзя так делать, это глобальная переменная получится.

явно не глобальная.
Re[4]: Передать массив из функции
От: GhostCoders Россия  
Дата: 29.06.10 14:48
Оценка:
Здравствуйте, dabeat_bf, Вы писали:

_>явно не глобальная.


Переменная не глобальная, но будут ограничения в использовании функции...

int* myfunc(int *b)
{
int i;
static long a[200];

for (i=0;i<200;i++)
a[i]=b[i];
return a;
}

int inputArray[200];
for(int i=0;i<200;i++)
  inputArray[i] = 0;

int result1 = myfunc(inputArray); // Первый раз все OK

int inputArray2[200];
for(int i=0;i<200;i++)
  inputArray2[i] = 1;
int result2 = myfunc(inputArray); // косяк!

// Сейчас result1 и result2
// Указывают на один и тотже массив
// который заполнен единицами
// в массиве result1 тоже все единицы
Третий Рим должен пасть!
Re[5]: Передать массив из функции
От: dabeat_bf Украина http://alexmogurenko.com
Дата: 29.06.10 15:01
Оценка:
Здравствуйте, GhostCoders, Вы писали:

GC>Здравствуйте, dabeat_bf, Вы писали:


_>>явно не глобальная.

GC>Переменная не глобальная, но будут ограничения в использовании функции...

знаю, знаю... но статик имеет право на жизнь, главное понимать что и зачем ты делаешь.
Re: Передать массив из функции
От: rm822 Россия  
Дата: 29.06.10 17:29
Оценка: :)
std::vector<int> myfunc(int *b)
{
  std::vector<int> a; 
  a.resize(200);

  for (int i=0;i<200;i++)
    a[i]=b[i];
  return a;
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Передать массив из функции
От: s.ts  
Дата: 29.06.10 17:30
Оценка:
В общем, нужна оценка типа "компенсировать минусы вставленные посту пока у тебя баллов хватает".
А то получается, что есть возможность только переоценить или недооценить, без учета будующих "оценщиков".
Сложновато, конечно, но иногда хочется
Как пример, пост на который я отвечаю — в качестве ответа на вопрос это не супер, но вполне себе нормальный вариант и минусов по моему явно не заслуживает, но и на плюсы тоже "не полный ответ"

Здравствуйте, Cris, Вы писали:

C>Здравствуйте, Аноним, Вы писали:


А>>Привет, необходимо передать массив заданный в функции:

А>>int* myfunc(int *b)
А>>{
А>>int i;
А>>long a[200];

А>>for (i=0;i<200;i++)

А>>a[i]=b[i];
А>>return a;
А>>}
А>>Подскажите, почему возвращаются только первые несколько элементов, как исправить? Заранее спасибо.
C>попробуй в функции обьявить массив a как
C>
C>static long a[200];
C>

C>он должен оставить массив после завершения функции
Re[6]: Передать массив из функции
От: monax  
Дата: 29.06.10 17:37
Оценка:
Здравствуйте, dabeat_bf, Вы писали:

_>знаю, знаю... но статик имеет право на жизнь, главное понимать что и зачем ты делаешь.


Какие плюсы у статика в этом случае, чтобы мириться с полученными недостатками?
Re[7]: Передать массив из функции
От: s.ts  
Дата: 29.06.10 18:10
Оценка:
Здравствуйте, monax, Вы писали:

M>Здравствуйте, dabeat_bf, Вы писали:


_>>знаю, знаю... но статик имеет право на жизнь, главное понимать что и зачем ты делаешь.


M>Какие плюсы у статика в этом случае, чтобы мириться с полученными недостатками?


сразу скажу, что мы говорим, конечно, про "pure c".
и тут скорее проще поставить вопрос иначе: какие плюсы у других реализаций ?
ответ: только реентерабельность.

т.е. если нет многопоточных вызовов, то static — это хорошее решение.
реентерабельное решение в чистом си сразу влечет дополнительные сложности реализации и использования.
потому многие чисто сишные функции именно так и реализованы — через static.
как-то так.
Re[8]: Передать массив из функции
От: s.ts  
Дата: 29.06.10 18:44
Оценка:
ST>т.е. если нет многопоточных вызовов, то static — это хорошее решение.
ST>реентерабельное решение в чистом си сразу влечет дополнительные сложности реализации и использования.
ST>потому многие чисто сишные функции именно так и реализованы — через static.
ST>как-то так.
да, считаем, что рекурсии тоже нет.
а по поводу массивов на стеке — тут тоже есть нехороший момент, когда они зависят от входных данных.
об этом много написано
Re[9]: Передать массив из функции
От: monax  
Дата: 29.06.10 19:03
Оценка:
Здравствуйте, s.ts, Вы писали:

ST>>сразу скажу, что мы говорим, конечно, про "pure c".

ST>>и тут скорее проще поставить вопрос иначе: какие плюсы у других реализаций ?
ST>>ответ: только реентерабельность.

Я вижу только один плюс использования статика — автоматическое освобождение памяти по окончании работы программы.

ST>>т.е. если нет многопоточных вызовов, то static — это хорошее решение.

ST>>реентерабельное решение в чистом си сразу влечет дополнительные сложности реализации и использования.
ST>>потому многие чисто сишные функции именно так и реализованы — через static.
ST>>как-то так.

ST>да, считаем, что рекурсии тоже нет.


Этих условий изначально не было, ну да ладно, ведь мы же рассматриваем разные ситуации.

В функции у нас создаётся массив. Ожидается, что дважды вызванная функция вернёт два разных массива. Использование статика приводит к возврату указателя на один и тот же массив (я приводил код, который это демонстрирует). Поэтому даже в однопоточной программе у нас есть проблема разделения данных, потому что они для всех общие. Т.е. мы получаем глобальную переменную.

Если у нас "pure c", то можно попробовать делать так:

#include <cstdio>
using namespace std;

#define SIZE 200

struct array {
    int data[SIZE];
};

array foo() {
    array tmp;
    for (int i = 0; i < SIZE; i++) {
        tmp.data[i] = i;
    }
    return tmp;
}

int main() {
    
    array a = foo();
    array b = foo();

    a.data[1] = 10;

    printf("a: %d, b: %d\n", a.data[1], b.data[1]);

    return 0;
}

Вывод программы

a: 10, b: 1


Как видишь, в таком случае у нас нет проблемы общих данных и нет проблемы освобождения памяти. Хотя тут будет расходоваться память при возврате структуры из функции, что плохо при больших SIZE.
Re[10]: Передать массив из функции
От: dabeat_bf Украина http://alexmogurenko.com
Дата: 29.06.10 19:31
Оценка: +1
Здравствуйте, monax, Вы писали:

M>В функции у нас создаётся массив. Ожидается, что дважды вызванная функция вернёт два разных массива. Использование статика приводит к возврату указателя на M>один и тот же массив (я приводил код, который это демонстрирует). Поэтому даже в однопоточной программе у нас есть проблема разделения данных, потому что они M>для всех общие.

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

M>Т.е. мы получаем глобальную переменную.

ну неглобальная это переменная, между статической и глобальной переменной есть большая разница
Re[10]: Передать массив из функции
От: s.ts  
Дата: 29.06.10 20:13
Оценка:
Здравствуйте, monax, Вы писали:

тоже вариант, но это ни "против" ни "в пользу" satic.
просто как вариант.
так что твой минус "статику" все равно трудно объяснить разумно.

P.S.
к слову, код у тебя не сишный.
в деталях, конечно, но все же

M>Если у нас "pure c", то можно попробовать делать так:


M>
M>#include <cstdio>
M>using namespace std;

M>#define SIZE 200

M>struct array {
M>    int data[SIZE];
M>};

M>array foo() {
M>    array tmp;
M>    for (int i = 0; i < SIZE; i++) {
M>        tmp.data[i] = i;
M>    }
M>    return tmp;
M>}

M>int main() {
    
M>    array a = foo();
M>    array b = foo();

M>    a.data[1] = 10;

M>    printf("a: %d, b: %d\n", a.data[1], b.data[1]);

M>    return 0;
M>}
M>

M>Вывод программы
M>

M>a: 10, b: 1


M>Как видишь, в таком случае у нас нет проблемы общих данных и нет проблемы освобождения памяти. Хотя тут будет расходоваться память при возврате структуры из функции, что плохо при больших SIZE.
Re[2]: Передать массив из функции
От: art_kuz Россия  
Дата: 30.06.10 06:30
Оценка:
Здравствуйте, rm822, Вы писали:

R>
R>std::vector<int> myfunc(int *b)
R>{
R>  std::vector<int> a; 
R>  a.resize(200);

R>  for (int i=0;i<200;i++)
R>    a[i]=b[i];
R>  return a;
R>}
R>


супер си-шный вариант
Re[11]: Передать массив из функции
От: monax  
Дата: 30.06.10 08:01
Оценка:
Здравствуйте, s.ts, Вы писали:

ST>так что твой минус "статику" все равно трудно объяснить разумно.


Минус как раз объяснить очень просто. Наведи на него курсор мыши и посмотри на высплывающую подсказку. Там написано "несогласен". Минус я использую именно для этого. Или теперь поставить минус значит что-то иное?

ST>P.S.

ST>к слову, код у тебя не сишный.
ST>в деталях, конечно, но все же

Если заменю array tmp на struct array tmp, ну и инклюды переделаю, тогда будет сишным?
Re[12]: Передать массив из функции
От: s.ts  
Дата: 30.06.10 08:40
Оценка:
Здравствуйте, monax, Вы писали:

ST>>так что твой минус "статику" все равно трудно объяснить разумно.

M>Минус как раз объяснить очень просто. Наведи на него курсор мыши и посмотри на высплывающую подсказку. Там написано "несогласен". Минус я использую именно для этого. Или теперь поставить минус значит что-то иное?

ну, значит не понятно "несогласие" со static

ST>>P.S.

ST>>к слову, код у тебя не сишный.
ST>>в деталях, конечно, но все же

M>Если заменю array tmp на struct array tmp, ну и инклюды переделаю, тогда будет сишным?

что-то типа того.
конечно тут это не принципиально, просто к слову пришлось
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.