Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.07.17;
Скачать: CL | DM;

Вниз

Переполнение стека при завершении программы.   Найти похожие ветки 

 
Zn   (2003-07-02 16:14) [0]

Работаю с простенькой программой перекодировки, созданной в DLL:

library UkrConv;

uses SysUtils,
Classes;

{$R *.RES}

function AToB(InpStr: PChar): PChar;register;
var i : Word;
begin
Result:=InpStr;
for i:=0 to Length(InpStr)-1 do
case Result[i] of
"a": Result[i]:="f";
"b": Result[i]:="e";
"c": Result[i]:="w";
"d": Result[i]:="q";
"x": Result[i]:="y";
"z": Result[i]:="k";
end;
end;

exports AToB;

begin
end.

Вызов такой:

procedure TForm1.Button1Click(Sender: TObject);
var sc: array [0..1022] of Char;
begin
StrPCopy(sc,Edit1.Text);
Label1.Caption:=StrPas(AToB(sc));
end;

Работает все нормально, но призакрытии программы выдаёт переполнение стека. Подскажите, пожалуйста, как корректно написать такой перекодировщик.


 
Семен Сорокин ©   (2003-07-02 16:19) [1]

for i:=0 to Length(InpStr)-1 do
case Result[i] of
"a": Result[i]:="f";
"b": Result[i]:="e";
"c": Result[i]:="w";
"d": Result[i]:="q";
"x": Result[i]:="y";
"z": Result[i]:="k";
end;

даже case не ругнулся?


 
Skier ©   (2003-07-02 16:20) [2]

1) Как AToB декларируется в host-приложении ?
2) Length -> StrLen


 
Zn   (2003-07-02 16:34) [3]


> Семен Сорокин © (02.07.03 16:19)


> даже case не ругнулся?

Не ругнулся.



> Skier © (02.07.03 16:20)
> 1) Как AToB декларируется в host-приложении ?

Так же, как и в DLL:

function Ukr866To1251(InpStr: PChar): PChar;register;
external "UkrConv.dll";




> 2) Length -> StrLen

Не помогает.
Я подозреваю, что некорркетно веду себя с PChar, но не знаю как правильно. Подскажите, как надо!


 
Romkin ©   (2003-07-02 16:37) [4]

Сделай везде вместо register stdcall
Да и с результатом у тебя проблемы. Явно выделяй память для Result


 
Serginio   (2003-07-02 16:44) [5]

Нет смысла объявлять как функцию так как изменяется текущая строк. Если бы передавал ссылку на реальную строку то Length конечно прокатывал бы но не в отношении статического массива.



 
Skier ©   (2003-07-02 16:46) [6]

>Zn
А вообще цель-то какая ?


 
Zn   (2003-07-02 16:47) [7]


> Сделай везде вместо register stdcall

stdcall пробовал, pascal тоже - безрезультатно.


> Явно выделяй память для Result

Это, конечно, можно. Но тогда в функцию AToB нужно добавлять ещё один параметр - размер буфера. А я и в вызове специально указал не PChar, а array [0..1022] of Char, чтоб не возиться с выделением памяти. И кстати, по идее Result и InpStr - одно и то же. Или я ошибаюсь?


 
Zn   (2003-07-02 16:53) [8]


> Skier © (02.07.03 16:46)


> А вообще цель-то какая ?

Да нужно e-mail другу слать в Южную Америку, он просил писать латинскими буквами по-русски, у них нет киррилицы. Вот и пытаюсь сделать перекодировщик, чтоб обычный текст переводил в латиницу. Заодно и попрактиковаться.
Извините, если отвлекаю по пустякам.


 
Serginio   (2003-07-02 16:58) [9]

Тебе уже несколько раз сказали
Используй не Length а StrLen и FillChar(sc,SizeOf(sc),0);



 
Skier ©   (2003-07-02 16:58) [10]

>Zn (02.07.03 16:53)
А ежели так сделать ? :

const
EncodeArraySize = ???;

type
TEncodeArray = array[0..EncodeArraySize - 1] of Char;


procedure AToB( var InputBuf : TEncodeArray); register;
begin
//bla-bla-bla...
end;


 
Romkin ©   (2003-07-02 17:00) [11]

А результат - это отдельная переменная, ты же явно присваиваешь, так что и память будь добр, выделяй. А лучше объяви процедуру
procedure AToB(InpStr, OutStr: PChar); stdcall;
Так понятнее? И сам для результата в вызывающей программе память выделяй (Ну или подавай одно и то же)


 
Zn   (2003-07-02 17:55) [12]


> Используй не Length а StrLen и FillChar(sc,SizeOf(sc),0);

Не помогает!



> Skier © (02.07.03 16:58)

То же самое!
Сдаётся мне, что прав всё-таки

> Romkin © (02.07.03 17:00)

память нужно выделять.
Спасибо! Попробую.


 
Romkin ©   (2003-07-02 18:09) [13]

Лучше сразу подавать в процедуру выходной параметр достаточной длины, посмотри, многие функции API так делают, например, GetSystemDirectory
Обрати внимание, что возвращается в результате. И соглашение stdcall, для универсальности.


 
Serginio   (2003-07-02 18:13) [14]

А почему ты решил, что из-за этого кода возникает переполнения стека. Смотри секции финализации и деструкторы вызывающиеся при завершении программы. Такое возможно при рекурсивном вызове процедур или же заталкивании в стек как прарамтра процедуры огромного статического массива.



Страницы: 1 вся ветка

Текущий архив: 2003.07.17;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.015 c
8-55660
skiph
2003-03-26 12:07
2003.07.17
Прозрачный фон рисунка


1-55596
Zigs
2003-07-03 13:12
2003.07.17
Можно ли в QReport сделать шрифт меньше чем 8?


6-55693
baracuda
2003-05-12 16:47
2003.07.17
send mail


7-55875
ng_softman
2003-05-09 10:26
2003.07.17
Как запустить процесс под другим пользователем?


3-55427
KIR
2003-06-24 11:51
2003.07.17
Тип NUMERIC в IB