У меня есть следующий код, и я не могу понять, почему возникнет исключение нарушения прав доступа? Я даже удалил все файлы OBJ, TDS и т. Д. И поместил его в новый проект, однако нарушение прав доступа происходит.
По сути, этот код отображает TListView в TFrame и должен показывать различные текущие времена по всему миру для разных часовых поясов.
Примечание. Код находится в C ++ Builder 6.
Может кто-нибудь помочь?
BLOODY-HELL-UPDATE :
Решаемые. Я не должен добавлять элементы в TListView в конструкторе TFrame. DUMB DUMB DUMB.
ОСНОВНОЕ ОБНОВЛЕНИЕ :
Кажется, что когда UpdateTimes () вызывается через таймер, свойство "li-> Deleting" имеет значение TRUE. Когда вызывается вне таймера, это ЛОЖЬ. Теперь, почему для "li-> Удаление" установлено значение "истина", потому что он вызывается из таймера? Если я сделаю:
if(li->Deleting == false)
{
li->Caption = "abcd";
}
Он не вводит if (), когда UpdateTimes () вызывается из таймера ...... argggggh !!!
ОБНОВЛЕНИЕ: Похоже, если я вызываю UpdateTimes () вне TTimer, он работает нормально. Но когда вызвано от таймера, это бросает Нарушение доступа. Что дает?
Заголовочный файл:
#ifndef CurrentTimes_FrameH
#define CurrentTimes_FrameH
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <ComCtrls.hpp>
#include <list>
using namespace std;
//---------------------------------------------------------------------------
struct LOCATIONTIMEINFORMATION
{
AnsiString TimeZoneName;
AnsiString PlaceName;
int UtcOffsetMinutes;
TListItem* ListItem;
};
//---------------------------------------------------------------------------
class TCurrentTimesFrame : public TFrame
{
__published: // IDE-managed Components
TTimer *Timer;
TListView *ListView;
void __fastcall TimerTimer(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TCurrentTimesFrame(TComponent* Owner);
//---------------------------------------------------------------------------
//User Code
//---------------------------------------------------------------------------
private:
list<LOCATIONTIMEINFORMATION> FTimeInformation;
typedef list<LOCATIONTIMEINFORMATION>::iterator LocationTimeInformationItr;
public:
void AddTimeInformation(LOCATIONTIMEINFORMATION lti);
void UpdateTimes();
};
//---------------------------------------------------------------------------
#endif
Файл CPP:
#include <vcl.h>
#pragma hdrstop
#include "CurrentTimes_Frame.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
//---------------------------------------------------------------------------
__fastcall TCurrentTimesFrame::TCurrentTimesFrame(TComponent* Owner): TFrame(Owner)
{
Timer->Enabled = false;
<strike>{
LOCATIONTIMEINFORMATION lti;
lti.TimeZoneName = "UTC";
lti.PlaceName = "Near Greenwich, England";
lti.UtcOffsetMinutes = 0;
AddTimeInformation(lti);
}</strike>
//UPADTED: Don't add TListItem from constructor
}
//---------------------------------------------------------------------------
void TCurrentTimesFrame::AddTimeInformation(LOCATIONTIMEINFORMATION lti)
{
TListItem* li = ListView->Items->Add();
li->Caption = lti.TimeZoneName;
li->SubItems->Add(lti.PlaceName);
li->SubItems->Add(lti.UtcOffsetMinutes);
li->SubItems->Add("<time will come here>");
lti.ListItem = li;
ShowMessage(AnsiString(lti.ListItem->ClassName())); //Correctly shows "TListItem"
FTimeInformation.push_back(lti);
{
LOCATIONTIMEINFORMATION temp = FTimeInformation.front();
ShowMessage(AnsiString(temp.ListItem->ClassName())); //Correctly shows "TListItem"
}
Timer->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TCurrentTimesFrame::TimerTimer(TObject *Sender)
{
UpdateTimes();
}
//---------------------------------------------------------------------------
void TCurrentTimesFrame::UpdateTimes()
{
Timer->Enabled = false;
TListItem* li;
for(LocationTimeInformationItr itr=FTimeInformation.begin();itr!=FTimeInformation.end();itr++)
{
li = itr->ListItem;
ShowMessage(AnsiString(li->ClassName())); //Access Violation:
/*
ShowMessage() above shows:
---------------------------
Debugger Exception Notification
---------------------------
Project XX.exe raised exception class EAccessViolation with message 'Access violation at address 4000567D in module 'rtl60.bpl'. Read of address 00000000'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
*/
}
Timer->Enabled = true;
}
//---------------------------------------------------------------------------
ОБНОВЛЕНИЕ Пример кода, демонстрирующий этот список, принимает элементы в качестве копии, а не ссылки.
(Насколько я вижу, пожалуйста, исправьте меня, если я делаю какую-то ошибку в коде ниже)
@ Крейг Янг:
Я в замешательстве ... Я думал, что структуры будут добавлены в список как копия , а не как ссылка?
Пожалуйста, посмотрите на код ниже, кажется, что копия делается? Или я что-то упускаю? Или ошибка кодирования ниже ??
void PopulateData()
{
AnsiString DebugText;
list<LOCATIONTIMEINFORMATION> Data;
LOCATIONTIMEINFORMATION OnStack;
//Prints "junk"
DebugText.sprintf("%s,%s,%d,%d",OnStack.TimeZoneName,OnStack.PlaceName,OnStack.UtcOffsetMinutes,(int)OnStack.ListItem);
OnStack.TimeZoneName = "UTC";
OnStack.PlaceName = "Near Greenwich, England";
OnStack.UtcOffsetMinutes = 10;
OnStack.ListItem = (TListItem*)20;
//OnStack:
DebugText.sprintf("%s,%s,%d,%d",OnStack.TimeZoneName,OnStack.PlaceName,OnStack.UtcOffsetMinutes,(int)OnStack.ListItem);
//Add data to list
Data.push_back(OnStack);
//Get struct from list
LOCATIONTIMEINFORMATION InList = Data.front();
//OnStack:
DebugText.sprintf("%s,%s,%d,%d",OnStack.TimeZoneName,OnStack.PlaceName,OnStack.UtcOffsetMinutes,(int)OnStack.ListItem);
//InList:
DebugText.sprintf("%s,%s,%d,%d",InList.TimeZoneName,InList.PlaceName,InList.UtcOffsetMinutes,(int)InList.ListItem);
//Change OnStack
OnStack.TimeZoneName = "NONE";
OnStack.PlaceName = "USA";
OnStack.UtcOffsetMinutes = 50;
OnStack.ListItem = (TListItem*)90;
//OnStack:
DebugText.sprintf("%s,%s,%d,%d",OnStack.TimeZoneName,OnStack.PlaceName,OnStack.UtcOffsetMinutes,(int)OnStack.ListItem);
//InList:
DebugText.sprintf("%s,%s,%d,%d",InList.TimeZoneName,InList.PlaceName,InList.UtcOffsetMinutes,(int)InList.ListItem);
//Change InList:
InList.TimeZoneName = "SOME";
InList.PlaceName = "BRAZIL";
InList.UtcOffsetMinutes = 66;
InList.ListItem = (TListItem*)88;
//OnStack:
DebugText.sprintf("%s,%s,%d,%d",OnStack.TimeZoneName,OnStack.PlaceName,OnStack.UtcOffsetMinutes,(int)OnStack.ListItem);
//InList:
DebugText.sprintf("%s,%s,%d,%d",InList.TimeZoneName,InList.PlaceName,InList.UtcOffsetMinutes,(int)InList.ListItem);
}