Re: Can't understand why these exceptions occur...



Ikke wrote:

Hi everybody,

I'm trying to write a little console application, which reads a command and a directory. If the command is "buffer", it needs to (recursively) find all the files in the given directory, and write them to a list. This list should be stored in / added to a buffer file which is read when the application starts.

The program I wrote works, but I get exceptions if the buffer file does not exist. As soon as it exists, the program works like a charm. I don't know what's going on, and I already tried to debug the application in Delphi and step through the entire application. As soon as the program ends, the exceptions start to pop up.

Here are the exceptions I get:
The instruction at "0x00403cde" referenced memory at "0x1088c260". The memory could not be "read".
Followed by:
The exception unknown software exception (0x0eedfade) occurred in the application at location 0x7c4ea4e1.
After this one, the first one is repeated over and over again, until I choose to cancel.

I'm at a loss here as to what I'm doing wrong - if I just read and write the buffer file without adding file info to it, I get no exceptions.

Here is my code:
---
program FileLocator;

{$APPTYPE CONSOLE}

uses
StrUtils,
SysUtils;

type
TBufferInfo = Record
name : String[255];
size : Int64;
End;

procedure BufferDirectory(source : String); forward;
procedure BufferFile(source, name : String; size : Int64); forward;
function FileMustBeBuffered(name : String) : boolean; forward;
procedure LoadCache(Const cacheName : String); forward;
procedure SaveCache(Const cacheName : String); forward;
procedure StartBufferingFiles(source : String); forward;

var
idx : Integer;
files : array[1..1000000] of TBufferInfo;

procedure BufferDirectory(source : String);
var
searchRec : TSearchRec;
found : Integer;
begin
// first find all the files
WriteLn('Buffering directory ' + source);
FindFirst(source + '\*.*', faAnyFile, searchRec);
repeat
{ Ignore '.' and '..' }
if (searchRec.Name <> '.') and
(searchRec.Name <> '..') and
(LowerCase(searchRec.Name) <> 'system volume information') and
(LowerCase(searchRec.Name) <> 'recycler') then
begin
if not ((searchRec.Attr and faDirectory) = faDirectory) then
begin
if FileMustBeBuffered(searchRec.Name) then
begin
BufferFile(source, searchRec.Name, searchRec.Size);
end;
end;
end;
found := FindNext(searchRec);
until (found <> 0);

// Then process the subdirectories
FindFirst(source + '\*.*', faAnyFile, searchRec);
repeat
{ Ignore '.' and '..' }
if (searchRec.Name <> '.') and
(searchRec.Name <> '..') and
(LowerCase(searchRec.Name) <> 'system volume information') and
(LowerCase(searchRec.Name) <> 'recycler') then
begin
if ((searchRec.Attr and faDirectory) = faDirectory) then
begin
BufferDirectory(source + '\' + searchRec.Name);
end;
end;
found := FindNext(searchRec);
until (found <> 0);

FindClose(searchRec);
end;

procedure BufferFile(source, name : String; size : Int64);
var
i : Integer;
blnFound : Boolean;
begin
WriteLn(' buffering: ' + source + '\' + name);

blnFound := false;
i := 1;
while (i < Length(files)) and (i <= idx) and Not(blnFound) do
begin
blnFound := (files[i].name = source + '\' + name);
Inc(i);
end;

if Not(blnFound) then
begin
if (idx < Length(files)) then
begin
files[idx].name := source + '\' + name;
files[idx].size := size;
Inc(idx);
end;
end;
end;

function FileMustBeBuffered(name : String) : boolean;
begin
result := AnsiEndsStr('.jpg', LowerCase(name))
or AnsiEndsStr('.gif', LowerCase(name))
or AnsiEndsStr('.tga', LowerCase(name))
or AnsiEndsStr('.tif', LowerCase(name))
or AnsiEndsStr('.bmp', LowerCase(name))
or AnsiEndsStr('.zip', LowerCase(name))
or AnsiEndsStr('.rar', LowerCase(name))
or AnsiEndsStr('.wmv', LowerCase(name))
or AnsiEndsStr('.avi', LowerCase(name))
or AnsiEndsStr('.mpg', LowerCase(name))
or AnsiEndsStr('.mpeg', LowerCase(name))
or AnsiEndsStr('.mov', LowerCase(name));
end;

procedure LoadCache(Const cacheName : String);
var
cache : File of TBufferInfo;
begin
try
if FileExists(cacheName) then
begin
AssignFile(cache, cacheName);
Reset(cache);
idx := 1;
while Not(eof(cache)) and (idx < Length(files)) do
begin
Read(cache, files[idx]);
Inc(idx);
end;
CloseFile(cache);
end;
except on e : Exception do
WriteLn('Exception occured: ' + e.Message);
end;
Exit;
end;

procedure SaveCache(Const cacheName : String);
var
cache : File of TBufferInfo;
begin
try
AssignFile(cache, cacheName);
ReWrite(cache);
idx := 1;
while (idx < Length(files)) do
begin
if (files[idx].name <> '') then
begin
Write(cache, files[idx]);
end;
Inc(idx);
end;
CloseFile(cache);
except on e : Exception do
WriteLn('Exception occured: ' + e.Message);
end;
end;

procedure StartBufferingFiles(source : String);
begin
BufferDirectory(source);
end;

begin
if ParamCount = 2 then
begin
LoadCache('FileLocatorBuffer.dat');

if LowerCase(ParamStr(1)) = 'buffer' then
begin
StartBufferingFiles(ParamStr(2));
end;

SaveCache('FileLocatorBuffer.dat');
end;
end.
---

Can anybody please shed some light on this? What am I doing wrong? Also, other hints, tips and tricks are always welcome!

Thanks,

Ikke
You need to fix your logic a bit here.

I assume the LoadCache is where you initiate the
buffer file.
You need to create the file... if it does not
yet exist!.
AssignFile(cache, CacheName);
If FileExist(cacheName) then
Begin
.....
as you were;
End else
Begin
// Clear all buffers to indicate an empty state.
Rewrite(Cache); // < Thats the magic call! :)
End;
CloseFile(Cache);

etc..
Reset assumes an Existing file, Rewrite just starts a
new file and replaces and existing one.

http://webpages.charter.net/jamie_5";

.



Relevant Pages

  • Cant understand why these exceptions occur...
    ... If the command is "buffer", ... but I get exceptions if the buffer file does ... procedure LoadCache(Const cacheName: String); forward; ... if (idx < Length(files)) then ...
    (alt.comp.lang.borland-delphi)
  • Newbee array pointer question
    ... I want to initialize a string in function, ... getting those STATUS_ACCESS_VIOLATION exceptions. ... void init(char* buffer) ...
    (comp.lang.c)
  • Re: Discovering variable types...
    ... >- but I suppose MS expect us to use wrappers ... memory allocations for your variables from disk as well. ... >They most certainly are of fixed size, changing the size of a String ... >>me to keep buffer size and current postion right in the memory block. ...
    (comp.lang.pascal.delphi.misc)
  • Re: Secure C library
    ... I read much of the new "security TR", and gee, I don't know. ... the buffer from the buffer size. ... It is not hard to design a better form of buffer and string handling. ... but this is just one example of how thoughtful interface design can ...
    (comp.std.c)
  • Re: Secure C library
    ... >> string functions don't make much sense once you add bounds-checking ... >> designing an interface just for the purpose of reducing the frequency ... > make buffer size decisions more visible, ... Bstrlib is also very interoperable with char *'s, ...
    (comp.std.c)