Здравствуйте, Аноним, Вы писали:
А>Привет, необходимо передать массив заданный в функции: А>int* myfunc(int *b) А>{ А>int i; А>long a[200];
А>for (i=0;i<200;i++) А>a[i]=b[i]; А>return a; А>} А>Подскажите, почему возвращаются только первые несколько элементов, как исправить? Заранее спасибо.
вообще не особо хорошо чтоб функция возвращала указатель, но если очень хочеться, то:
Здравствуйте, Аноним, Вы писали:
А>Привет, необходимо передать массив заданный в функции: А>int* myfunc(int *b) А>{ А>int i; А>long a[200];
А>for (i=0;i<200;i++) А>a[i]=b[i]; А>return a; А>} А>Подскажите, почему возвращаются только первые несколько элементов, как исправить? Заранее спасибо.
Тебе вообще повезло, что программа не завершилась аварийно
Так делать нельзя. Потому что массив "a", выделен на стеке. А что происходит со стеком функции, при выходе из функции? Правильно! Он освобождается, и, таким образом, ты возвращаешь невалидный указатель. Как вариант можешь выделить память в куче, и не забыть ее освободить, чтобы не было утечек. А можешь просто передать указатель на выделенную память, куда ты потом скопируешь массив, как это было продемонстрировано выше.
Здравствуйте, Аноним, Вы писали:
А>Привет, необходимо передать массив заданный в функции: А>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];
он должен оставить массив после завершения функции
После такого создания массив нужно копировать. Проще сразу создавать его в выделенной для него памяти и возвращать на него указатель, как предложили выше.
Здравствуйте, 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); // Первый раз все OKint inputArray2[200];
for(int i=0;i<200;i++)
inputArray2[i] = 1;
int result2 = myfunc(inputArray); // косяк!
// Сейчас result1 и result2
// Указывают на один и тотже массив
// который заполнен единицами
// в массиве result1 тоже все единицы
Здравствуйте, GhostCoders, Вы писали:
GC>Здравствуйте, dabeat_bf, Вы писали:
_>>явно не глобальная. GC>Переменная не глобальная, но будут ограничения в использовании функции...
знаю, знаю... но статик имеет право на жизнь, главное понимать что и зачем ты делаешь.
В общем, нужна оценка типа "компенсировать минусы вставленные посту пока у тебя баллов хватает".
А то получается, что есть возможность только переоценить или недооценить, без учета будующих "оценщиков".
Сложновато, конечно, но иногда хочется
Как пример, пост на который я отвечаю — в качестве ответа на вопрос это не супер, но вполне себе нормальный вариант и минусов по моему явно не заслуживает, но и на плюсы тоже "не полный ответ"
Здравствуйте, 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>он должен оставить массив после завершения функции
Здравствуйте, monax, Вы писали:
M>Здравствуйте, dabeat_bf, Вы писали:
_>>знаю, знаю... но статик имеет право на жизнь, главное понимать что и зачем ты делаешь.
M>Какие плюсы у статика в этом случае, чтобы мириться с полученными недостатками?
сразу скажу, что мы говорим, конечно, про "pure c".
и тут скорее проще поставить вопрос иначе: какие плюсы у других реализаций ?
ответ: только реентерабельность.
т.е. если нет многопоточных вызовов, то static — это хорошее решение.
реентерабельное решение в чистом си сразу влечет дополнительные сложности реализации и использования.
потому многие чисто сишные функции именно так и реализованы — через static.
как-то так.
ST>т.е. если нет многопоточных вызовов, то static — это хорошее решение. ST>реентерабельное решение в чистом си сразу влечет дополнительные сложности реализации и использования. ST>потому многие чисто сишные функции именно так и реализованы — через static. ST>как-то так.
да, считаем, что рекурсии тоже нет.
а по поводу массивов на стеке — тут тоже есть нехороший момент, когда они зависят от входных данных.
об этом много написано
Здравствуйте, 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.
Здравствуйте, monax, Вы писали:
M>В функции у нас создаётся массив. Ожидается, что дважды вызванная функция вернёт два разных массива. Использование статика приводит к возврату указателя на M>один и тот же массив (я приводил код, который это демонстрирует). Поэтому даже в однопоточной программе у нас есть проблема разделения данных, потому что они M>для всех общие.
мы же не знаем что на самом деле должна делать функия... может нас устраивает что данные постоянно будут меняться, а может мы будем пользоваться результатом функции и только потом еще раз вызывать ее, тогда статик уже доаольно интересный вариант.
M>Т.е. мы получаем глобальную переменную.
ну неглобальная это переменная, между статической и глобальной переменной есть большая разница
M>Как видишь, в таком случае у нас нет проблемы общих данных и нет проблемы освобождения памяти. Хотя тут будет расходоваться память при возврате структуры из функции, что плохо при больших SIZE.
Здравствуйте, s.ts, Вы писали:
ST>так что твой минус "статику" все равно трудно объяснить разумно.
Минус как раз объяснить очень просто. Наведи на него курсор мыши и посмотри на высплывающую подсказку. Там написано "несогласен". Минус я использую именно для этого. Или теперь поставить минус значит что-то иное?
ST>P.S. ST>к слову, код у тебя не сишный. ST>в деталях, конечно, но все же
Если заменю array tmp на struct array tmp, ну и инклюды переделаю, тогда будет сишным?
Здравствуйте, monax, Вы писали:
ST>>так что твой минус "статику" все равно трудно объяснить разумно. M>Минус как раз объяснить очень просто. Наведи на него курсор мыши и посмотри на высплывающую подсказку. Там написано "несогласен". Минус я использую именно для этого. Или теперь поставить минус значит что-то иное?
ну, значит не понятно "несогласие" со static
ST>>P.S. ST>>к слову, код у тебя не сишный. ST>>в деталях, конечно, но все же
M>Если заменю array tmp на struct array tmp, ну и инклюды переделаю, тогда будет сишным?
что-то типа того.
конечно тут это не принципиально, просто к слову пришлось