2014-11-13 122 views
1

我试图存储一个指向Tqueue中的记录的指针,然后稍后退出指针并提取数据,但是与指针混淆并继续得到'抽象错误'什么是在Delphi中存储记录指针在Tqueue中的正确方法

任何人都可以请看看我做错了什么,并建议我正确的解决方案?

(顺便说一句,一开始我是有没有^,但后来意识到我的错误,但很惊讶,它仍然给了一个错误)

记录认为被发送到一个SMTP服务器的电子邮件数据,它采用了TStringList中保持身体的每一行,另外一个来保存每个附件的文件名

这是用来存储电子邮件数据

TPtrEmailData = ^TEmailDataRec; 
TEmailDataRec = record 
       ToAddr  : string; //one email address 
       CcAddr  : string; //addresses delimitated by semicolons 
       BccAddr  : string; //addresses delimitated by semicolons 
       Subject  : String; 
       Body : TStrings; //each string contains one line of the body 
       attachments: TStrings;//each string contains a filename 
       end; 

要创建我使用

的记录的记录结构
function TFrmSendEmail.CreateNewEmailRec: TPtrEmailData; 
var 
    EmailRecPtr : TPtrEmailData; 
begin 
new(EmailRecPtr); //make a new record 
EmailRecPtr^.Body := Tstrings.Create ; 
EmailRecPtr^.attachments := Tstrings.create; 
result := EmailRecPtr ; 
end; 

和dequeing我用,当我使用下面的排队队列中的新记录指针

procedure TFrmSendSllSmtptEmail.DestroyEmailRec(EmailRecPtr : TPtrEmailData); 
//frees memory for the Tstrings and then frees the record 
begin 
freeandnil(EmailRecPtr^.Body); //free one Tstringlist 
FreeAndNil(EmailRecPtr^.attachments); //and the other 
FreeAndNil(EmailRecPtr); //now free the precord pointer 
end; 

CreateNewEmailRec被调用后释放他们,通过在备忘录和列表框containig日ebody和附件。这是我得到错误的地方。

procedure TFrmSendEmail.AddToEmailQueue(ToAddr, CCAddr, 
          BccAddr,Subject:String; 
          Body: Tmemo; Attachments: TListBox); 
var 
i : integer; 
s : string; 
EmailRecPtr : TPtrEmailData; 
begin 
EmailRecPtr := CreateNewEmailRec; //allocate memory 
            //deallocated in RemoveFromEmailQueue 
EmailRecPtr^.ToAddr := ToAddr; 
EmailRecPtr^.CCAddr := CCAddr; 
EmailRecPtr^.BccAddr := BccAddr; 
for I := 0 to Attachments.Count - 1 do 
    begin 
    s := Attachments.Items[i]; 
    EmailRecPtr^.attachments.add(s); <---- !!! get abstract error here 
    end; 
for I := 0 to Body.lines.Count - 1 do 
    begin 
    s := Body.lines[i]; 
    EmailRecPtr^.Body.Add(s) ; 
    end; 
EmailQueue.Enqueue(EmailRecPtr); 
end; 

,当我出队指针

procedure TFrmSendEmail.RemoveFromEmailQueue(var ToAddr, 
                CCAddr, 
                BccAddr, 
                Subject: String; 
                var Body, 
                Attachments: TStringlist); 
var 
    EmailRecPtr :TPtrEmailData; 
    i : integer; 
    s : string; 
begin 
if EmailQueue.Count > 0 then 
    begin 
    Body.Clear; 
    Attachments.Clear; 

    EmailRecPtr := EmailQueue.Dequeue; //get pointer to next record 
    ToAddr := EmailRecPtr^.ToAddr; //populate procedure parameters 
    CCAddr := EmailRecPtr^.CCAddr; 
    BccAddr := EmailRecPtr^.BccAddr; 
    for EmailRecPtr^.attachments.Count - 1 do 
     begin 
     s := EmailRec^.attachments[i]; 
     Attachments.Add(s) ; 
     end; 
    for I := 0 to EmailRecPtr ^.Body.Count - 1 do 
     begin 
     s := EmailRecPtr ^.Body[i]; 
     Body.Add(s); 
     end; 

    DestroyEmailRec(EmailRecPtr); //release memory 
end; 

到RemoveFromEmailQueue的调用传递一对夫妇创建TStringLists

TheBody := Tstringlist.Create ; 
TheAttachments := Tstringlist.create; 
try 
    RemoveFromEmailQueue(ToAddr, CCAddr, BccAddr, Subject,TheBody,TheAttachments); 
// do stuff with the data; 
finally 
    TheBody.Free; 
    TheAttachments.Free; 
end; 

哦使用数据DestroyEmailRec被调用,并且队列声明为

var 
    EmailQueue : Tqueue<TPtrEmailData>; 
+1

FreeAndNil是你做的东西的对象上。在使用New分配的指针上使用Dispose。 –

+0

配置匹配新 –

回答

3

由于您使用了一个抽象对象(TStrings),因此您会得到“抽象错误”!在TFrmSendEmail.CreateNewEmailRecTStringList替换TStrings

function TFrmSendEmail.CreateNewEmailRec: TPtrEmailData; 
begin 
new(result); //make a new record 
Result^.Body := TStringList.Create ; 
Result^.attachments := TStringList.create; 
end; 

而且,你不能使用免费的记录FreeAndNil!所以,你的方法来释放记录应该像

procedure TFrmSendSllSmtptEmail.DestroyEmailRec(EmailRecPtr : TPtrEmailData); 
//frees memory for the Tstrings and then frees the record 
begin 
EmailRecPtr^.Body.Free; //free one Tstringlist 
EmailRecPtr^.attachments.Free; //and the other 
Dispose(EmailRecPtr); //now free the precord pointer 
end; 
+0

整天盯着我的代码,我没注意到Tstrings! – user3209752

+0

..和我应该知道更好,并使用配置,而不是FreeAndNil。只是显示这个论坛的价值。它所需要的只是一双新鲜的眼睛!谢谢你 – user3209752

+4

@ user3209752:实际上,你应该得到一个编译器警告,你正在实例化一个抽象类“TStrings”。 –

相关问题