Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DasBlub

Alter Hase

  • »DasBlub« ist der Autor dieses Themas

Beiträge: 802

Wohnort: Schweiz

Beruf: Programmierer

  • Private Nachricht senden

1

08.09.2007, 14:52

Zugriffsverletzung bei ReadINIString

Ich wollte Breakanoid so umschreiben, dass die Levels aus einer INI-Datei gelesen werden. Dazu habe ich die ReadINI Funktionen aus Galactica kopiert.

Meine INI-Datei (Ausschnitt):


Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Levels]
LevelCount  = 2


[Level1]
RowCount    = 4

Row1Blocks  = " 1  1  1 "
Row1Pos     = -8, 0, 2

Row2Blocks  = "12 111 21"
Row2Pos     = -8, 0, 1

Row3Blocks  = "12     21"
Row3Pos     = -8, 0, 0

Row4Blocks  = " 112 211 "
Row4Pos     = -8, 0, -1


Ich bekomme nun jedoch immer eine Zugriffsverletzung, wenn die Funktion GetPrivateProfileString aufgerufen wird.

C-/C++-Quelltext

1
TB_INFO(ReadINIInt("Levels", "LevelCount"));


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
// Liest einen int-Wert aus der INI-Datei

int CGame::ReadINIInt(char* pcSection,
                      char* pcKey)
{
    char acString[256];

    // String lesen

    ReadINIString(pcSection, pcKey, acString, 256);
    if(!strcmp(acString, "[NOT FOUND]")) return 12345678;

    // In int-Wert umwandeln

    return atoi(acString);
}


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Liest einen String aus der INI-Datei

tbResult CGame::ReadINIString(char* pcSection,
                              char* pcKey,
                              char* pcOut,
                              int iBufferSize)
{
    TB_INFO(pcSection);
    TB_INFO(pcKey);
    TB_INFO(iBufferSize);

    // pruefen, ob datei existiert

    if(!tbFileExists("Data\\Breakanoid.ini")) {
        TB_ERROR("Data\\Breakanoid.ini wurde nicht gefunden!", TB_ERROR);
    }

    // String lesen

    GetPrivateProfileString(pcSection, pcKey, "[NOT FOUND]",
                            pcOut, iBufferSize,
                            "Data\\Breakanoid.ini");

    TB_INFO(pcOut);

    return TB_OK;
}


ich bin froh um jedem tipp. danke bereits im voraus.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

11.09.2007, 09:50

Probier mal:

Quellcode

1
2
[Levels] 
LevelCount=2


Ansonsten sollte es egtl heißen:

C-/C++-Quelltext

1
2
int CGame::ReadINIInt( const char* pcSection, const char* pcKey );
tbResult CGame::ReadINIString( const char* pcSection, const char* pcKey, char* pcOut, int iBufferSize );
@D13_Dreinig

DasBlub

Alter Hase

  • »DasBlub« ist der Autor dieses Themas

Beiträge: 802

Wohnort: Schweiz

Beruf: Programmierer

  • Private Nachricht senden

3

15.09.2007, 15:27

hab beides probiert. geht leider immer noch nicht :cry: .

Zitat von »"Visual C++ 2005 Express Edition"«

Unbehandelte Ausnahme bei 0x1013b36c in Breakanoid.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000100.


zusätzlich geht vs dann in den disasembly:

Zitat von »"disassembly"«

1013B36C movsx ecx,byte ptr [eax]

DarioFrodo

Treue Seele

Beiträge: 349

Wohnort: Kerkau, 100km nördlich von Magdeburg

Beruf: Selbstständig

  • Private Nachricht senden

4

16.09.2007, 13:44

Wichtig ist das pcOut auf einen gültigen speicherbereich mit der Größe iBufferSize zeigt.

C-/C++-Quelltext

1
2
3
//Pseudo Code:

char acBuffer[256];
ReadINIString("Sektor", "Key", acBuffer, 256);


oder

C-/C++-Quelltext

1
2
3
//Pseudo Code:

char* pcBuffer = new char[256];
ReadINIString("Section", "Key", pcBuffer, 256);
Erst wenn der letzte Fluss vergiftet,
der letzte Baum gefällt,
der letzte Fisch gefangen,
dann werdet ihr merken, dass man Geld nicht essen kann

Man verkauft die Erde nicht, auf der die Menschen wandeln.

- Indianerweisheiten

Ich bin auch ein einhornimmond ;)

DasBlub

Alter Hase

  • »DasBlub« ist der Autor dieses Themas

Beiträge: 802

Wohnort: Schweiz

Beruf: Programmierer

  • Private Nachricht senden

5

16.09.2007, 13:48

wie du bereits in meinem 1. post lesen kannst, sieht die funktion ReadINIInt ja bereits so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
// Liest einen int-Wert aus der INI-Datei

int CGame::ReadINIInt(const char* pcSection,
                      const char* pcKey)
{
    char acString[256];

    // String lesen

    ReadINIString(pcSection, pcKey, acString, 256);
    if(!strcmp(acString, "[NOT FOUND]")) return 12345678;

    // In int-Wert umwandeln

    return atoi(acString);
}


und ReadINIString sieht folgendermassen aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Liest einen String aus der INI-Datei

tbResult CGame::ReadINIString(const char* pcSection,
                              const char* pcKey,
                              char* pcOut,
                              int iBufferSize)
{
    TB_INFO(pcSection);
    TB_INFO(pcKey);
    TB_INFO(iBufferSize);

    // pruefen, ob datei existiert

    if(!tbFileExists("Data\\Breakanoid.ini")) {
        TB_ERROR("Data\\Breakanoid.ini wurde nicht gefunden!", TB_ERROR);
    }

    // String lesen

    GetPrivateProfileString(pcSection, pcKey, "[NOT FOUND]",
                            pcOut, iBufferSize,
                            "Data\\Breakanoid.ini");

    TB_INFO(pcOut);

    return TB_OK;
}


der fehler tritt immer bei GetPrivateProfileString auf.

DasBlub

Alter Hase

  • »DasBlub« ist der Autor dieses Themas

Beiträge: 802

Wohnort: Schweiz

Beruf: Programmierer

  • Private Nachricht senden

6

16.09.2007, 15:43

ich hab gerade herausgefunden, dass das problem an iBufferSize liegt.

wenn ich statt:

C-/C++-Quelltext

1
2
3
4
// String lesen

    GetPrivateProfileString(pcSection, pcKey, "[NOT FOUND]",
                                  pcOut, iBufferSize,
                          "Data\\Breakanoid.ini");


das schreibe:

C-/C++-Quelltext

1
2
3
4
// String lesen

    GetPrivateProfileString(pcSection, pcKey, "[NOT FOUND]",
                                  pcOut, 256,
                          "Data\\Breakanoid.ini");


funktioniert es.

es wundert mich jedoch, da die funktion folgendermassen aussieht:

C-/C++-Quelltext

1
2
3
4
tbResult CGame::ReadINIString(const char* pcSection,
                              const char* pcKey,
                              char* pcOut,
                              int iBufferSize)


und der aufruf:

C-/C++-Quelltext

1
ReadINIString(pcSection, pcKey, acString, 256);

DarioFrodo

Treue Seele

Beiträge: 349

Wohnort: Kerkau, 100km nördlich von Magdeburg

Beruf: Selbstständig

  • Private Nachricht senden

7

16.09.2007, 16:42

Ja ja, unmögliche Fehler, habe ich auch schon mal geahbt, sehr ärgerlich.
Und Zeitraubend.
Erst wenn der letzte Fluss vergiftet,
der letzte Baum gefällt,
der letzte Fisch gefangen,
dann werdet ihr merken, dass man Geld nicht essen kann

Man verkauft die Erde nicht, auf der die Menschen wandeln.

- Indianerweisheiten

Ich bin auch ein einhornimmond ;)

DasBlub

Alter Hase

  • »DasBlub« ist der Autor dieses Themas

Beiträge: 802

Wohnort: Schweiz

Beruf: Programmierer

  • Private Nachricht senden

8

16.09.2007, 16:44

[resolved]

ich hab soeben den fehler gefunden! :D :D :D :D :D :D :D :D :D :D :D

aus irgend einem grund funktioniert atoi() nicht richtig.

original:

C-/C++-Quelltext

1
return atoi(acString);


neu:

C-/C++-Quelltext

1
return (int)acString;

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

9

16.09.2007, 17:26

ernsthaft? :shock:

Also wenn das wirklich das von dir gewünschte Ergebnis ist dann Respect!
Was du nämlich im wesentlichen tust ist die Konvertierung von acString erst in einen Pointer und dann in einen int Wert - ich kann mir einfach nicht erklären was dir das bringen soll!

DasBlub

Alter Hase

  • »DasBlub« ist der Autor dieses Themas

Beiträge: 802

Wohnort: Schweiz

Beruf: Programmierer

  • Private Nachricht senden

10

16.09.2007, 17:28

sry, funktionierte doch nicht :oops: .

aber jetzt geht es einwandfrei:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Liest einen int-Wert aus der INI-Datei

int CGame::ReadINIInt(const char* pcSection,
                      const char* pcKey)
{
    char acString[256];

    // String lesen

    ReadINIString(pcSection, pcKey, acString, 256);
    if(!strcmp(acString, "[NOT FOUND]")) return 12345678;

    // In int-Wert umwandeln

    int iTemp = atoi(acString);
    return iTemp;
}


aus irgend einem grund funktioniert die direkte rueckgabe nicht. deshalb der umweg über iTemp.

Werbeanzeige