我在使用Delphi保存不同的大型数据库类型时遇到问题。它包含TItem的数组[1..3500],后者又有两个数组[1..50]和[1..20]。我得到一个堆栈溢出,除非我将变量设置为指针并使用下面的GetMem,FreeMem命令,但后来我无法保存它。代码如下。
procedure TDatabase.SaveDB;
var
TempDB: ^TSaveDB;
K, X: integer;
sComment, sTitle, sComposer, sISDN, sCategory: string;
begin
GetMem(TempDB, SizeOf(TSaveDB));
TempDB.CatCount := fCategoryCount;
TempDB.ItemCount := fItemCount;
for K := 1 to fCategoryCount do
TempDB.Categories[K] := fCategories[K];
for K := 1 to fItemCount do
begin
fItems[K].ReturnSet(sTitle, sComposer, sCategory, sISDN, sComment);
with TempDB.Items[K] do
begin
Title := sTitle;
Composer := sComposer;
Category := sCategory;
ISDN := sISDN;
end;
TempDB.Items[K].Comments[1] := Copy(sComment, 1, 255);
Delete(sComment, 1, 255);
TempDB.Items[K].Comments[2] := Copy(sComment, 1, 255);
Delete(sComment, 1, 255);
TempDB.Items[K].Comments[3] := Copy(sComment, 1, 255);
Delete(sComment, 1, 255);
TempDB.Items[K].Comments[4] := Copy(sComment, 1, 255);
Delete(sComment, 1, 255);
TempDB.Items[K].KeyWCount := fItems[K].GetKeyCount;
for X := 1 to fItems[K].GetKeyCount do
TempDB.Items[K].Keywords[X] := fItems[K].GetKeywords(X);
end;
AssignFile(DBSave, fSaveName);
Rewrite(DBSave);
Write(DBSave, TempDB);
Closefile(dBSave);
FreeMem(TempDB, sizeof(TSaveDB));
end;
答案 0 :(得分:3)
使用GetMem或SetLength或TList / TObjectList并一次写入一个TSaveDB文件。要么 更改文件类型并使用BlockWrite一次写入所有内容。甚至更好:使用TFileStream。
答案 1 :(得分:1)
您的问题出在“写入”声明中。用任意指针做事会导致各种奇怪的行为。如果你使用TFileStream而不是当前的方法重写它,你会更容易。
答案 2 :(得分:1)
扩展梅森的答案:
从不读取或写入指针,句点。如果你不再只是运行你的程序,成功的几率从无穷小变为零,那么在实现它的过程中获得任何合理的东西都会花费大量的运气。
相反,您需要读取和写入指针指向的内容。
另请注意,除非您在兼容模式下运行“string”为“string [255]”,否则声明中未指定长度的任何字符串都是指针 - 此模式仅适用于兼容当这是我们唯一的字符串时编写的非常旧的代码。
由于您似乎只是简单地编写了整个内容,因此没有理由使用固定大小的记录来玩游戏。只需将每个字段写入流,在写入字符串之前写入字符串的长度,以便可以正确加载它。该文件将更小,没有任何内容被截断。
另外,正如他所说,使用tFileStream。旧格式用于磁盘上留下的记录文件,在这种情况下没有理由使用它。