|
Вопрос # 3 012/ вопрос открыт / |
|
Здравствуйте, эксперты!
Столкнулся с очень интересной проблемой . Одна из частей моей программы перемещает некие файлы из одной папки в другую, адреса считываются с ini и записываются в string. Все работает отлично, пока адресс не длиннее 25 символов, а если
это происходит, то перемещение файлов прерывается с ошибкой Windows. Использую Dialogs, DB, DBCtrls, DBTables. Могу написать еще много подробностей, но не знаю,что именно важно.А да, возможно роковое число не 25, а 30, тк прога создает папку 2009\ по этому арессу.
 |
Вопрос задал: Mav3rick (статус: Посетитель)
Вопрос отправлен: 20 июля 2009, 11:03
Состояние вопроса: открыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 15; последнее сообщение — 20 июля 2009, 13:42; участников в обсуждении: 4.
|
Егор (статус: 10-ый класс), 20 июля 2009, 11:43 [#1]:
1. что за ошибка windows? подробнее, пожалуйста
2. из ini-файла данные считываются корректно? проверяли это?
3. приведите, пожалуйста, код, осуществляющий перемещение файлов.
Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его.
— Donald E. Knuth.
|
|
min@y™ (статус: Доктор наук), 20 июля 2009, 11:45 [#2]:
4. И выложи сам ini-файл посмотреть.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Mav3rick (статус: Посетитель), 20 июля 2009, 11:50 [#3]:
1 стандартная ошибка: обнаружена ошибкаюПриложение будет закрыто и тд...
прога консольная с параметром...в ноде пишет runtime error 216
2 да, во всех остальных случаях все гладко. и тут все считывается нормально
3 код абсолютно стандартный
procedure CreateBuffer( Names : array of string; var P : TBuffer );
var
I, J, L : Integer;
begin
for I := Low( Names ) to High( Names ) do
begin
L := Length( P );
SetLength( P, L + Length( Names[ I ] ) + 1 );
for J := 0 to Length( Names[ I ] ) - 1 do P[ L + J ] := Names[ I, J + 1 ];
P[ L + J ] := #0;
end;
SetLength( P, Length( P ) + 1 );
P[ Length( P ) ] := #0;
end;
function CopyFiles( Handle:HWND; Src : array of string; Dest : string; Move : Boolean; AutoRename : Boolean ) : Integer;
var
SHFileOpStruct : TSHFileOpStruct;
SrcBuf : TBuffer;
begin
CreateBuffer( Src, SrcBuf );
with SHFileOpStruct do
begin
Wnd := Handle;
wFunc := FO_COPY;
if Move then wFunc := FO_MOVE;
pFrom := Pointer( SrcBuf );
pTo := PChar( Dest );
fFlags := 0;
if AutoRename then fFlags := FOF_RENAMEONCOLLISION;
fAnyOperationsAborted := False;
hNameMappings := nil;
lpszProgressTitle := nil;
end;
Result := SHFileOperation( SHFileOpStruct );
SrcBuf := nil;
end;
|
|
Mav3rick (статус: Посетитель), 20 июля 2009, 11:52 [#4]:
ini :
[settings]
P1 = C:\Depo7\Test\Send\
P2 = C:\Depo7\Test\Send\2009\
P3 = C:\Depo7\Test\Disk_h\SEND\
N1 = a195
N2 = *
HOLIDAY = HD_LIST.dbf
|
|
min@y™ (статус: Доктор наук), 20 июля 2009, 12:00 [#5]:
Пиши последовательно все операции в лог-файл, чтобы локализовать ошибку.
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
|
Mav3rick (статус: Посетитель), 20 июля 2009, 12:01 [#6]:
самое интересное заключается в том, что несколько файлов в эту папку он перебрасывает, а потом видимо зависает.
|
|
Mav3rick (статус: Посетитель), 20 июля 2009, 12:04 [#7]:
дада, прописываю в логах перемещение
Info:=adress2 + F.Name + ' --> ' + s + F.Name;
WriteLn(T1,Info);
CopyFiles( Handle, fileadress ,s,True, True );
последние 2 строчки(первая как пример нормальной):
C:\Depo7\Test\Send\2009\a1951402.907 --> C:\Depo7\Test\Disk_h\SEND\2009\200907\a1951402.907
C:\Depo7\Test\Send\2009\a1951402.ouf --> C:\Depo7\Test\Disk_h\
|
|
Вадим К (статус: Академик), 20 июля 2009, 12:13 [#8]:
смотрим внимательно на код
SrcBuf : TBuffer;
begin
CreateBuffer( Src, SrcBuf );
понятно, что SrcBuf это какой то либо класс, либо структура. и в CreateBuffer он инициализируется.
идем в эту процедуру и понимаем, что это просто динамический массив символов. Но тогда конструкция L := Length( P ); возратит неведомо что. Хотя скорее всего 0.
Дальше смотрим на кусочек
SetLength( P, Length( P ) + 1 );
P[ Length( P ) ] := #0;
в первой строке мы удлинили её на один символ и Length( P ) в этих двух строках возвращает разные значения. И скорее всего, если там действительно динамический массив, то вторая строка обращается за пределы массива... Удивительно, как ещё винт не форматируется...
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Mav3rick (статус: Посетитель), 20 июля 2009, 12:19 [#9]:
хммм, это часть программы была вчастую скатана с авторитетного портала. Там это было образцом работы с файлами... Я не сильно вглядывался в код, тк она работает. Вы указали на ошибку, но разьве она связана с моим вопросом?
|
|
Вадим К (статус: Академик), 20 июля 2009, 12:32 [#10]:
я думаю, что да. потому что я считаю, что при таком коде в SrcBuf находиться мусор. И это причина всего.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Вадим К (статус: Академик), 20 июля 2009, 13:19 [#12]:
если type TBuffer = array of Char;
то P[ Length( P ) ] := #0; - выход за пределы массива.
скорее всего должно быть что то вида
P[ Length( P ) - 1 ] := #0;
А то что ресурс авторитетный, ещё ничего не значит.
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Mav3rick (статус: Посетитель), 20 июля 2009, 13:28 [#13]:
да, я сам уже понял=) спасибо, вроде заработало. Вот только интересно, как это связано с длинами строк?
|
|
Вадим К (статус: Академик), 20 июля 2009, 13:40 [#14]:
а никак. это UB (в переводе "неопределённое поведение"). Можно конечно залезть глубоко в дебри компилятора, менеджера памяти и ОС и вывести объяснение. Но зачем?
Галочка "подтверждения прочтения" - вселенское зло.
|
|
Mav3rick (статус: Посетитель), 20 июля 2009, 13:42 [#15]:
действительно, намного приятней относиться к компилятору по-человечески=)
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|