J'ai le code suivant, et pour la vie de moi, je ne peux pas comprendre pourquoi il y aurait une exception de violation d'accès? J'ai même supprimé tous les fichiers OBJ, TDS, etc et le mettre dans un nouveau projet, toujours la violation d'accès se produit. Essentiellement, ce code affiche un TListView dans un TFrame et doit montrer les différents temps actuels autour du monde pour différents fuseaux horaires.Violation d'accès fou dans C++ Builder 6
Note: Le code est dans le constructeur de C 6.
Quelqu'un peut-il aider?
BLOODY-HELL-UPDATE: Résolu. Je ne devrais pas ajouter d'éléments à TListView dans le constructeur TFrame. DUMB DUMB DUMB.
Mise à jour majeure: Il semble que lorsque l'on appelle le UpdateTimes() par la minuterie, la « Li-> Suppression » propriété est TRUE. Lorsqu'il est appelé en dehors de la minuterie, il est FAUX. Maintenant, pourquoi "li-> Suppression" serait-il réglé sur "vrai" parce qu'il est appelé à partir de la minuterie? Si je fais:
if(li->Deleting == false)
{
li->Caption = "abcd";
}
Il ne marche pas entrer dans le cas(), quand UpdateTimes() est appelée à partir de la minuterie ...... argggggh !!!
MISE À JOUR: Il semble que si j'appelle UpdateTimes() en dehors du TTimer, cela fonctionne très bien. Mais lorsqu'il est appelé à partir de la minuterie, il lance la violation d'accès. Ce qui donne?
tête de fichier:
#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
RPC fichier:
#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;
}
//---------------------------------------------------------------------------
MISE À JOUR Un exemple de code demo'ing cette liste prend des éléments comme la copie, pas de référence. (Pour autant que je peux voir, s'il vous plaît me corriger si im faire une erreur dans le code ci-dessous)
@Craig Young:
Je suis confus ... Je pensais que struct seraient ajoutés à la liste en tant que copie pas comme référence? S'il vous plaît jeter un oeil sur le code ci-dessous, il semble qu'une copie est en cours? Ou est-ce que je manque quelque chose de rudimentaire? Ou une erreur de codage ci-dessous ??
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);
}
RÉSOLU. D'ACCORD. Ce que j'ai appris est que, N'ajoutez pas d'éléments à TListView dans le constructeur. Comment DUMB. – Liao
Pas tout à fait; votre 'solution' peut avoir changé quelque chose d'autre, mais créer des TListItems dans le constructeur ne devrait pas causer de problèmes de manière inhérente. S'il vous plaît consulter ma réponse détaillée. –
Mon erreur. J'ai tendance à avoir plus d'un état d'esprit Delphi; et sans STL, notre TList tiendra toujours des articles par référence à moins qu'un effort spécial soit fait autrement. Cependant, j'ai testé votre code original, et cela fonctionne parfaitement - donc je pense que votre erreur est ailleurs. S'il vous plaît poster comment vous utilisez le cadre. –