Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 13.03.2010, 16:56
Smerch66 Smerch66 вне форума
Прохожий
 
Регистрация: 31.10.2009
Сообщения: 43
Репутация: 10
По умолчанию Передача массива в процедуру с помощью указателя

var
DATA : array of Float; //динамический массив, размер которого задаю в тексте программы.
DATAlength: integer;
i,num: integer;

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

procedure maxelement(mass : array of Float; mNFFT : integer; var element : integer);
begin
element:=0;
for i:=1 to mNFFT-1 do
begin
if abs(mass[i])>abs(mass[element]) then
element:=i;
end;
end;

//далее идёт кусок из текста, в котором обращаюсь к процедуре
setlength(DATA, DATAlength);
...
maxelement(DATA, DATAlength, num);


Правильно ли я понимаю, что если оставить всё как описано выше, то в процедуру передаётся массив целиком, а не указатель на него?

Если всё таки это передача указателя, то почему когда передаю массивы размерности примерно 100000 - 150000 элементов всё в порядке. А как передаю массив примерно на 360000 элементов, выскакивает ошибка в ходе выполнения программы, о каком-то переполнении.
Подскажите пожалуйста как решить эту проблему.
Ответить с цитированием
  #2  
Старый 13.03.2010, 17:07
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

Stack overflow - переполнение стэка

Код:
pArrAddr := @any_array[Low(any_array)] // указатель на первый элемент в массиве

Pointer(any_array) := pArrAddr; // из указателя обратно в массив (не копирует массив! просто переменную указывает на существующий массив)

pArrAddr это и есть тот самый указатель на массив
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;

Последний раз редактировалось AleD, 13.03.2010 в 17:10.
Ответить с цитированием
  #3  
Старый 13.03.2010, 17:12
Smerch66 Smerch66 вне форума
Прохожий
 
Регистрация: 31.10.2009
Сообщения: 43
Репутация: 10
По умолчанию

Очень извиняюсь, но не очень понятно.
Можно как-нибудь написать относительно того текста и тех переменных которые у меня уже имются? Очень прошу!
Самое интересное просто как это передать в процедуру.

Последний раз редактировалось Smerch66, 13.03.2010 в 17:14.
Ответить с цитированием
  #4  
Старый 13.03.2010, 17:14
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

Код:
var
DATA : array of Float; //динамический массив, размер которого задаю в  тексте программы.
DATAlength: integer;
i,num: integer;

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

procedure maxelement(pMass : Pointer; mNFFT : integer; var element  : integer);
var
mass: array of Float;
begin
Pointer(mass) := pMass;
element:=0;
for i:=1 to mNFFT-1 do
  begin
  if abs(mass[i])>abs(mass[element]) then
  element:=i;
  end;
end;

//далее  идёт кусок из текста, в котором обращаюсь к процедуре
setlength(DATA, DATAlength);
...
maxelement(@DATA[Low(DATA)], DATAlength, num);

как то так
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;
Ответить с цитированием
  #5  
Старый 13.03.2010, 17:42
Smerch66 Smerch66 вне форума
Прохожий
 
Регистрация: 31.10.2009
Сообщения: 43
Репутация: 10
По умолчанию

Спасибо большое получилось!

То есть теперь в этой процедуре не нужно делать очистку массива?
Finalize(mass);

И ещё один важный вопрос: что это было за переполнение стека и с чем оно связано?
Ответить с цитированием
  #6  
Старый 13.03.2010, 17:48
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

Цитата:
Сообщение от Smerch66
Спасибо большое получилось!

То есть теперь в этой процедуре не нужно делать очистку массива?
Finalize(mass);

И ещё один важный вопрос: что это было за переполнение стека и с чем оно связано?
если вы очистите массив в этой процедуре то он будет пуст и за пределами функции, кароче говоря DATA и mass это одно и тоже, одна информация, одну память используют

перед вызовом функции в стек (просто буфер определённого размера, регулируется в настройках делфи) записываются передаваемые параметры, если стек переполняется то и происходит соответствующее исключение
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;
Ответить с цитированием
  #7  
Старый 13.03.2010, 18:15
Smerch66 Smerch66 вне форума
Прохожий
 
Регистрация: 31.10.2009
Сообщения: 43
Репутация: 10
По умолчанию

Проблема возникла! Вобщем как только процедура завершает свою работу, автоматически очищаются оба массива mass и DATA. Понял теперь что это один и тот же массив, то всё же, он очищается сам, без всяких команд по завершению этой процедуры
Ответить с цитированием
  #8  
Старый 13.03.2010, 18:22
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

Цитата:
Сообщение от Smerch66
Проблема возникла! Вобщем как только процедура завершает свою работу, автоматически очищаются оба массива mass и DATA. Понял теперь что это один и тот же массив, то всё же, он очищается сам, без всяких команд по завершению этой процедуры
в конце процедуры добавьте этот кусок:
Код:
Pointer(mass) := nil;
и всё будет в порядке
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;
Ответить с цитированием
  #9  
Старый 13.03.2010, 18:30
Smerch66 Smerch66 вне форума
Прохожий
 
Регистрация: 31.10.2009
Сообщения: 43
Репутация: 10
По умолчанию

Теперь уже окончательно всё получилось! Спасибо вам огромнейшее!
Осталось только 2 вопроса:
1) что благодаря этой последней команде происходит, и что происходило без неё?
2) как я могу поднять вам репутацию? а то ещё не совсем освоился с возможностями форума.

Спасибо!!!
Ответить с цитированием
  #10  
Старый 13.03.2010, 18:35
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

Цитата:
Сообщение от Smerch66
Теперь уже окончательно всё получилось! Спасибо вам огромнейшее!
Осталось только 2 вопроса:
1) что благодаря этой последней команде происходит, и что происходило без неё?
2) как я могу поднять вам репутацию? а то ещё не совсем освоился с возможностями форума.

Спасибо!!!
1) Четно говоря сам не знаю, но в некоторых парсерах и интерфейсах если число refCount (число переменных привязанных к данным) равняется нулю, то эти данные больше не нужны и они удаляются. Хотя здесь наврятли такое...
2) Значок весов справа от сообщения коим помог
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;
Ответить с цитированием
  #11  
Старый 13.03.2010, 18:43
Smerch66 Smerch66 вне форума
Прохожий
 
Регистрация: 31.10.2009
Сообщения: 43
Репутация: 10
По умолчанию

Нажимаю на весы, а там сообщение:
"Вы должны добавить отзыв кому-то еще, прежде чем сможете снова добавить ее AleD."

Ну думаю, может я уже дааавно оставлял свою благодарность. В результате оставил отзыв другому человку, и потом снова попробовал на ваши весы нажать и то же самое(
Ответить с цитированием
  #12  
Старый 13.03.2010, 18:47
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

Цитата:
Сообщение от Smerch66
Нажимаю на весы, а там сообщение:
"Вы должны добавить отзыв кому-то еще, прежде чем сможете снова добавить ее AleD."

Ну думаю, может я уже дааавно оставлял свою благодарность. В результате оставил отзыв другому человку, и потом снова попробовал на ваши весы нажать и то же самое(
да не суть, мне эти циферки в 2 байта (или 4) не важны
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;
Ответить с цитированием
  #13  
Старый 13.03.2010, 18:49
Asinkrit Asinkrit вне форума
Местный
 
Регистрация: 29.10.2009
Сообщения: 446
Репутация: 271
По умолчанию

Можно и проще было это сделать)
Код:
...
type
  TFloatArray = array of Float;
...
function GetMaxEement(const FloatArray:TFloatArray):Integer;
var
  i:Integer;
begin
  Result:=0;
  if Length(FloatArray) > 1 then
    for i:=Low(FloatArray)+1 to High(FloatArray) do
      if abs(FloatArray[i]) > abs(FloatArray[Result]) then
        Result:=i;
end;
...
Ответить с цитированием
  #14  
Старый 13.03.2010, 19:01
Smerch66 Smerch66 вне форума
Прохожий
 
Регистрация: 31.10.2009
Сообщения: 43
Репутация: 10
По умолчанию

А в этом случае, как я понимаю, в функцию будет передаваться весь массив, а не указатель на него?
Ответить с цитированием
  #15  
Старый 13.03.2010, 19:03
Аватар для AleD
AleD AleD вне форума
Активный
 
Регистрация: 21.02.2009
Адрес: г.Краснокаменск
Сообщения: 383
Репутация: 91
По умолчанию

Цитата:
Сообщение от Smerch66
А в этом случае, как я понимаю, в функцию будет передаваться весь массив, а не указатель на него?
эм... нет, тоже указатель, я просто как то при слове "указатель" сразу и подумал про Pointer. const сделан для упрощения программирования, как например String (это тоже указатель )
__________________
TAleD = class(TUser)
public
function HelpMe(ASubject, ARequest: String): String;
function GiveMeExample(ASubject: String): TStringList;
procedure WriteReview(APost: Integer; ADescription: TStringList);
end;
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 07:20.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter