2014-11-13 119 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」。 –

相關問題