2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу 1, 2  След.
 
 Создание динамического массива внутри функции
Сообщение14.05.2017, 15:19 
Вопрос такой.
Есть функция, в теле которой создаётся динамический массив (выделяется память и выполняется заполнение определёнными значениями), вот прототип:
Код:
int inTabl(double* Tabl, double* x, double* y, int nObs, int Ord, double q)

Tabl - это указатель на массив, а остальное - входные параметры.

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

Сейчас попробовал переделать функцию таким образом:
Код:
double* inTabl(double* x, double* y, int nObs, int Ord, double q)
,
т.е. теперь указатель на массив явно определён как возвращаемое значение.

Как ни странно, в таком виде всё работает отлично.
Подскажите пожалуйста в чём тут может быть дело? (память выделяю через malloc(), освобождаю уже в основной программе)

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 15:24 
Andrey_Kireew в сообщении #1216344 писал(а):
возвращает длину массива и указатель
Что значит "возвращает указатель"? По идее, он должен быть передан в функцию как параметр, функция может его использовать, но не может его "возвращать". По-видимому, где-то в этом месте Вы сделали что-то неправильное (а чтобы понять, что именно, нужно увидеть код).

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 15:49 
Я просто неправильно выразился, конечно он передаётся в неё как параметр,
сначала я его объявляю
Код:
double* Tabl;

а затем вызываю функцию
Код:
int inTabl(Tabl, x, y, nObs, Ord, q)

она выделяет для Tabl память и потом заполняет её значениями,

но потом в основной программе по этому указателю не могу ничего прочитать.

Во втором же варианте (а там как раз функция именно возвращает указатель, т.к. он ей ни откуда из вне не передаётся), всё работает нормально.

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 16:00 
Andrey_Kireew в сообщении #1216349 писал(а):
она выделяет для Tabl память и потом заполняет её значениями,
Ну и как именно выделяется память? По-видимому, Вы делаете это с помощью *alloc или new, а затем пишете в Tabl указатель на выделенную область памяти. Но, поскольку код Вы упорно приводить не хотите, и даже язык, который обсуждается, по имеющимся отрывкам однозначно не определить...

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 16:03 
Andrey_Kireew в сообщении #1216349 писал(а):
она выделяет для Tabl память и потом заполняет её значениями,

Он же передаётся по значению, а не по имени. Мало ли что там внутри функции со значением этого указателя делается -- назад-то новое значение не возвращается.

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 16:05 
Аватара пользователя
Надо понимать, что double* Tabl - это не массив, а всего лишь указатель, причём в данном случае параметр, передаваемый в функцию по значению. Обратно он никак не сможет вернуться. Если ему что-то присвоить, то это произойдёт только внутри функции.

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 16:11 
Вот код нерабочего варианта
Код:
# include ......
int inTabl(double* Tabl, double* x, double* y, int nObs, int Ord, double q)
{
// здесь объявления разных переменных
int Len=(Ord+nObs)<<1; Len++;
   
Tabl = (double*) malloc(SizeTabl);
memset(Tabl,0,SizeTabl);                     // заполнение нулями

    for (int ii=0; ii<nObs; ii++)
    {
     .............................
    *(Tabl+ib)=sg_y;                         
    *(Tabl+ib+nObs)=-sg_y;                 

    .............................
    }

return Len;
}

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 16:16 
Хм, а почему на это компилятор не ругается? На переопределение переменной?

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 16:17 
Аватара пользователя
Andrey_Kireew
Прочитайте уже наконец Кернигана-Ритчи, вопросы же элементарные.

Если у Вас функция выглядит примерно так
Код:
int f(double * data, int n)
{
  data = malloc(sizeof(double) * n);
  return 0;
}
и идет вызов
Код:
void main()
{
  double * a = NULL;
  f(a, 3);
}

то естественно, переменная a останется нулем, а выделенная память потеряется.

При вызове функции все параметры копируются в регистры/стек и работа внутри функции идет с этими копиями.
В данном случае значение a (NULL) при вызове f копируется в локальную переменную data, потом эта data меняется, в итоге в data остается адрес выделенной памяти, а a так и остается нулем. При выходе из функции f переменная data теряется.

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 16:18 
Andrey_Kireew в сообщении #1216359 писал(а):
double* Tabl = (double*) malloc(SizeTabl);
Ну да, так и есть. Вы передаете указатель в функцию и изменяете его внутри функции. Соответственно, с внешней точки зрения ничего не происходит, информация о том, что указатель изменился, обратно не возвращается.

-- 14.05.2017, 16:19 --

Dmitriy40 в сообщении #1216361 писал(а):
Хм, а почему на это компилятор не ругается? На переопределение переменной?
По стандарту это не ошибка. Мог бы выскочить warning, но это зависит от настроек компилятора.

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 16:24 
Pphantom в сообщении #1216363 писал(а):
По стандарту это не ошибка. Мог бы выскочить warning, но это зависит от настроек компилятора.
Ужасно. Оно должно было выскочить. И если кто-то его запрещает/отменяет, то без глубокого понимания происходящего он делает это очень зря. ИМХО. Я при отладке программ включаю все варнинги и с причиной каждого внимательно разбираюсь.

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение14.05.2017, 16:26 
Уже немножко начинаю догадываться

-- 14.05.2017, 17:35 --

Всё как пишет Xaositect , код был с ошибкой - сейчас исправлено.

-- 14.05.2017, 17:54 --

Действительно, значение измениться не может. Напрашивается вывод, что нужно использовать указатель на указатель

Код:
int inTabl(double** Tabl, double* x, double* y, int nObs, int Ord, double q)
{
*Tabl = (double*) malloc(SizeTabl);
memset(*Tabl,0,SizeTabl);
..............
return Len;
}



void main()
{
double** Tabl;
int Len=inTabl(* Tabl, x, y, nObs, Ord, q);

}


в таком виде будет правильно?

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение15.05.2017, 17:54 
Аватара пользователя
Ещё освойте замечательный форумный тег syntax.

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение15.05.2017, 18:41 
Andrey_Kireew в сообщении #1216367 писал(а):
Напрашивается вывод, что нужно использовать указатель на указатель
Именно.

 
 
 
 Re: Создание динамического массива внутри функции
Сообщение15.05.2017, 19:09 
Аватара пользователя
Andrey_Kireew в сообщении #1216367 писал(а):
Напрашивается вывод, что нужно использовать указатель на указатель

Зависит от языка.

 
 
 [ Сообщений: 16 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group