Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Передача указателя из dll


Автор: фигурист 27.10.2008, 20:28
Возник вот какой вопрос: 

В программе вычисляется массив Length.

float K1 =0.1;
float *s=NULL;
float Length_max = 0;
/*Вызываем бибилиотеку Traektory1_DLL*/
s=Return_massive();
Length[0]=ceil(s[0]/K1);
Length[1]=ceil(s[1]/K1);
Length[2]=ceil(s[2]/K1);
Length[3]=ceil(s[3]/K1);
Length[4]=ceil(s[4]/K1);
Length[5]=ceil(s[5]/K1);
Length[6]=ceil (s[6]/K1);
Length_max=ceil (s[7]/K1);

Библиотека Traektory1_DLL
float *Return_massive(void)
{
float *a=NULL;
float d[9];
d[0]=6.20;
d[1]=37.60;
d[2]=76.00;
d[3]=553.60;
d[4]=4.00;
d[5]=4.00;
d[6]=17.00;
d[7]=553.60;
d[8]=7;
a=d;
return a;
}

Если вычислять так, то программа правильно вычисляет только 4 значения, остальные элементы массива принимают произвольное значение. 
Установил, что дело в функции ceil(x). Если делать так 

Length[0]=(s[0]/K1)+1; 
    
то программа правильно вычисляет 7 значений. 
Тот же эффект при использовании floor, ceill, floorl

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

Автор: SVN74 27.10.2008, 21:03
Цитата(фигурист @  27.10.2008,  20:28 Найти цитируемый пост)
float *a=NULL;

Попробуй вынести за пределы функции.

Автор: 586 27.10.2008, 21:14
Цитата(фигурист @  27.10.2008,  21:28 Найти цитируемый пост)
float *Return_massive(void)
{
float *a=NULL;
float d[9];

d[0]=6.20;
d[1]=37.60;
d[2]=76.00;
d[3]=553.60;
d[4]=4.00;
d[5]=4.00;
d[6]=17.00;
d[7]=553.60;
d[8]=7;
a=d;
return a;
}

Ты пытаешься вернуть указатель на локальную переменную. В пределах функции массива d не существует.
Используй malloc / free или директиву static.

Автор: SVN74 27.10.2008, 21:20
float *d;
float *Return_massive(void)
{
d = new float[9];
d[0]=6.20;
d[1]=37.60;
d[2]=76.00;
d[3]=553.60;
d[4]=4.00;
d[5]=4.00;
d[6]=17.00;
d[7]=553.60;
d[8]=7;
return d;
}

Автор: mes 27.10.2008, 21:28
Цитата

float *d;
float *Return_new_massive(void)
{
float * d = new float[9];
d[0]=6.20;
...
d[8]=7;
return d;
}

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

Автор: 586 27.10.2008, 21:29
Цитата(SVN74 @  27.10.2008,  22:20 Найти цитируемый пост)
float *d;
float *Return_massive(void)
{
d = new float[9];
d[0]=6.20;
d[1]=37.60;
d[2]=76.00;
d[3]=553.60;
d[4]=4.00;
d[5]=4.00;
d[6]=17.00;
d[7]=553.60;
d[8]=7;
return d;
}

Код не поддерживает многопоточность, из-за общей переменной. Следует объявить указатель d локально:
Код

float *Return_massive(void)
{
    float *d = new float[9];
    d[0]=6.20;
    d[1]=37.60;
    d[2]=76.00;
    d[3]=553.60;
    d[4]=4.00;
    d[5]=4.00;
    d[6]=17.00;
    d[7]=553.60;
    d[8]=7;
    return d;
}

Автор: SVN74 27.10.2008, 21:47
Цитата(586 @  27.10.2008,  21:29 Найти цитируемый пост)
Код не поддерживает многопоточность, из-за общей переменной. Следует объявить указатель d локально:

код C++ Builder

float *Return_massive(void)
{
    float *d = new float[9];
    d[0]=6.20;
    d[1]=37.60;
    d[2]=76.00;
    d[3]=553.60;
    d[4]=4.00;
    d[5]=4.00;
    d[6]=17.00;
    d[7]=553.60;
    d[8]=7;
    return d;
}

(Утечка памяти) А как же очистка памяти? Тогда для данной модели надо передавать указатель не через return.
Вопрос о многопоточности не стоял.
В данном случае...
На мой взгляд надо применять глобальный указатель с последующей очисткой, либо возвращать не через return с последующей очисткой внутри функции, иначе хоть указатель и локальный, память не освобождается...


Автор: mes 27.10.2008, 21:51
Цитата(SVN74 @  27.10.2008,  21:47 Найти цитируемый пост)
На мой взгляд надо применять глобальный указатель с последующей очисткой, либо возвращать не через return с последующей очисткой внутри функции, иначе хоть указатель и локальный, память не освобождается...

 smile без комментариев 

Автор: фигурист 27.10.2008, 22:06
Большое спасибо всем ответившим smile 

Я тут новичок поэтому Ваши ответы очень пригодятся для дальнейшего  изучения СИ++

Попробую пределать прогу. Спасибо

Добавлено через 13 минут и 49 секунд
 
Работает, урра.  smile 

Автор: SVN74 28.10.2008, 00:02
Вот накидал один из (рабочих, без утечки памяти) способов обмена данными между динамическими массивами...
================================================================================= 
void __fastcall TForm1::Proba(float *c[])
{
  int M = 8;
  float *g = new float[M];
  g[0]=14.63;
  g[1]=73.8;
  g[2]=35.66;
  g[3]=755.85;
  g[4]=33.6;
  g[5]=732.53;
  g[6]=332.64;
  g[7]=73.83;
  memcpy(&(*c[0]),g,sizeof(g)*M);
  delete [] g;
}
//---------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 int M =8;
 float *R = new float[M];
 for(int y=0;y<M;y++)
 {
  Proba(&R);
  Memo1->Lines->Add(FloatToStr(R[y]));
 }
 delete [] R;
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)