[c++] access violation met new char * [x]

Pagina: 1
Acties:

  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 20:01
IDE: borland 5.01

k heb niet veel verstand van C of C++ wat betreft pointerd ed.
voor t programma heb ik de volgende functie geschreven:
t gaat fout op regel 12, dan komt er een error:
code:
1
2
3
4
Thread stopped d:\cam.exe:
Fault: access violation at 
0x40146c: write of address
0x6c775a


C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
unsigned char ** avarage (unsigned char ** pixels, unsigned int width, unsigned int height)
{
    /**************************************************
   * avarage returns the pixels avaraged             *
   * the avarage of a pixel is taken in the area     *
   * of 'size' around the pixel calculated           *
   * Update, size is fixed as 1, calculates faster   *
   **************************************************/
   unsigned int i, x ,y;
   unsigned long totalofpixels;
   cout << "test1\n";
   unsigned char ** avgpixels = new unsigned char * [width];
      cout << "test2\n";
   for (i = 0; i < width; i++)
        avgpixels[i] = new unsigned char[height];

   for (y = 1; y < (height - 1); y++){
    for (x = 1; x < (width - 1); x++){
        totalofpixels = pixels[x-1][y-1];
       totalofpixels += pixels[x][y-1];
         totalofpixels += pixels[x+1][y-1];
         totalofpixels += pixels[x-1][y];
         totalofpixels += pixels[x][y];
         totalofpixels += pixels[x+1][y];
         totalofpixels += pixels[x-1][y+1];
         totalofpixels += pixels[x][y+1];
         totalofpixels += pixels[x+1][y+1];
        avgpixels[x][y] = char (totalofpixels / 9);
      }
   }
   return avgpixels;
}


de code rond regel 12,14,15 heb ik elders gevonden op got voor t defineren van een multidimensional array.
wat doe ik precies fout?

[ Voor 3% gewijzigd door curry684 op 21-04-2004 14:54 ]

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Ik zie de knaller zelf ook zo snel niet maar dit is natuurlijk een idioot langzame methode van alloceren.

Doe maar gewoon:
C++:
1
unsigned char* Pixels = new char[Width * Height];

Of encapsuleer je bitmapachtige dinges gewoon netjes :)

Professionele website nodig?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het is C++ neem ik aan? Je gebruikt namelijk new, maar je gebruikt de c code tag. Aangezien het wel compilet ga ik er maar even vanuit dat het C++ is ;)

Maar aan je code is niets fout, de pixels array die je meegeeft aan je functie is waarschijnlijk niet groot genoeg. Maar daar heb je een debugger voor, niet GoT

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 20:01
t vreemde is dat t met oneven breedte en hoogte van t plaatje wel goed gaat :?

en k heb wel gedebugged, maar daar snap ik niet veel van, k ben nie bepaald een c guru

plaatjes van 641 bij 481 werkt wel, dus lijkt me sterk dat t aan de hoeveelheid geheugen ligt :?

[ Voor 55% gewijzigd door Super_ik op 21-04-2004 14:44 ]

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Als jij nou eerst eens ging controleren op welke regel je precies die access violation krijgt

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 20:01
regel 12: unsigned char ** avgpixels = new unsigned char * [width];

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • SilencerNL
  • Registratie: Juli 2002
  • Laatst online: 25-05 13:59

SilencerNL

No remorse

code:
1
for (y = 1; y < (height - 1); y++){


Je array is te klein... Stel je height is 40, dan maakt ie je array 1 t/m 38... denk dat dat moet zijn 0 tm 39

verander die 1 dus in 0. en haal die -1 weg geld voor beide loops

[ Voor 6% gewijzigd door SilencerNL op 21-04-2004 14:47 ]

Don't dream your life, live your dreams!


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Bliep, dat slaat nergens op. Hij alloceert een grootte van height, en loopt er vervolgens doorheen van 1 t/m height-1. De buitenste rand blijft dus ongeaccessed, en de array is derhalve groot genoeg. Wat jij nu suggereert is dat ie ook nog eens een breder gebied door moet gaan zoeken, wat natuurlijk niet helpt als je array al te klein was

[ Voor 27% gewijzigd door .oisyn op 21-04-2004 14:48 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Silencer_NL schreef op 21 april 2004 @ 14:46:
code:
1
for (y = 1; y < (height - 1); y++){


Je array is te klein... Stel je height is 40, dan maakt ie je array 1 t/m 38... denk dat dat moet zijn 0 tm 39

verander die 1 dus in 0. en haal die -1 weg geld voor beide loops
En hoe gaat dit een knaller 3 regels erboven oplossen? ;)

[ Voor 9% gewijzigd door curry684 op 21-04-2004 14:48 ]

Professionele website nodig?


  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 20:01
Silencer_NL schreef op 21 april 2004 @ 14:46:
code:
1
for (y = 1; y < (height - 1); y++){


Je array is te klein... Stel je height is 40, dan maakt ie je array 1 t/m 38... denk dat dat moet zijn 0 tm 39

verander die 1 dus in 0. en haal die -1 weg geld voor beide loops
dat heeft nix meer met t defineren van de array te maken, maar met t proces

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • SilencerNL
  • Registratie: Juli 2002
  • Laatst online: 25-05 13:59

SilencerNL

No remorse

.oisyn schreef op 21 april 2004 @ 14:47:
Bliep, dat slaat nergens op. Hij alloceert een grootte van height, en loopt er vervolgens doorheen van 1 t/m height-1. De buitenste rand blijft dus ongeaccessed, en de array is derhalve groot genoeg. Wat jij nu suggereert is dat ie ook nog eens een breder gebied door moet gaan zoeken, wat natuurlijk niet helpt als je array al te klein was
:X

zit vandaag ook al te lang naar code te kijken... je hebt helemaal gelijk.

*Silencer gaat maar eens koffie pauze houden

Don't dream your life, live your dreams!


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 15:28

Robtimus

me Robtimus no like you

offtopic:
Gemiddelde is average, met een e dus

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 15:28

Robtimus

me Robtimus no like you

Super_ik schreef op 21 april 2004 @ 14:45:
regel 12: unsigned char ** avgpixels = new unsigned char * [width];
Ik denk het niet.
Bij mij gaat het volgende goed:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
unsigned char **arr = new unsigned char *[4];
for (int i = 0; i < 4; i++)
    arr[i] = new unsigned char[4];
for (int i = 0; i < 4; i++)
    for (int j = 0; j < 4; j++)
        arr[i][j] = i + j;
for (int i = 0; i < 4; i++)
{
    for (int j = 0; j < 4; j++)
        printf("%4d", arr[i][j]);
    printf("\n");
}
Waar het fout gaat in je code is volgens mij in het gebruik van pixels in je functie. Als ik nml onder mijn code de volgende regel toevoeg, dan gaat het pas fout:
C++:
1
unsigned char **avg = avarage(0, 4, 4);
Comment ik dan in de functie de assignments aan totalpixels uit dan gaat het goed.

Bij mij komt het door het gebruik van pixels in de functie.


Verkeerde aanroep, met avarage(arr, 4, 4) gaat het hier goed (Borland C++ 5.5.1).

[ Voor 15% gewijzigd door Robtimus op 21-04-2004 15:49 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 25-05 20:56
Kun je d'r misschien een compleet voorbeeld van maken, met dus een typische aanroep die fout gaat? Ik ben er van overtuigd dat de code die je weergeeft helemaal goed is. De fout zal dus ergens anders zitten.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 20:01
k heb regel 28 vervangen voor
avgpixels[x][y] = pixels[x][y];

daar geeft de debugger een fout aan. alleen wat die debugger allemaal laat zien zegt me verder weinig helaas

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Super_ik schreef op 21 april 2004 @ 16:00:
k heb regel 28 vervangen voor
avgpixels[x][y] = pixels[x][y];

daar geeft de debugger een fout aan. alleen wat die debugger allemaal laat zien zegt me verder weinig helaas
Hoe komt ie in regel 28 als ie in regel 12 knalt? :?

Professionele website nodig?


  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 20:01
omdat ie nie altijd knalt :?
tussen regel 28 en 27 heb ik
cout << x << " " << y << '\n'; gezet
hij komt tot
x = 121
y = 2

k wou dat ik er iets van snapte, gvd

[ Voor 73% gewijzigd door Super_ik op 21-04-2004 16:09 ]

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • Coca-Cola
  • Registratie: Maart 2001
  • Laatst online: 14:34
je gaat out of bounds bij je array.. ik denk zowiezo dat deze code niet gaat doen wat je precies wilt... hij returned nu een array dat niet helemaal gevuld is (avgpixels[0][0] etc.).
Maar goed, bij bv 3,3 (dus een array van [0][0] tot [2][2]) probeer je ook [3][0] t/m [3][2] te benaderen, nou kan dit lang goed gaan, maar op een gegeven moment krijg je idd access violations.
Je probleem is eigenlijk dat de pixels aan de randen niet 8 buren hebben. Dus ik denk dat je ofwel voor de rand pixels een andere oplossing moet gaan zoeken, ofwel forlussen gaan gebruiken met wat if's erin.

[ Voor 22% gewijzigd door Coca-Cola op 21-04-2004 16:47 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 25-05 20:56
Coca-Cola schreef op 21 april 2004 @ 16:45:
je gaat out of bounds bij je array.. ik denk zowiezo dat deze code niet gaat doen wat je precies wilt... hij returned nu een array dat niet helemaal gevuld is (avgpixels[0][0] etc.).
Maar goed, bij bv 3,3 (dus een array van [0][0] tot [2][2]) probeer je ook [3][0] t/m [3][2] te benaderen, nou kan dit lang goed gaan, maar op een gegeven moment krijg je idd access violations.
Onzin; als je de thread nu doorleest (want dat heb je blijkbaar niet gedaan) dan had wordt al voorgekauwd waarom het probleem dat jij schetst niet aan de orde is.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Super_ik schreef op 21 april 2004 @ 16:04:
omdat ie nie altijd knalt :?
tussen regel 28 en 27 heb ik
cout << x << " " << y << '\n'; gezet
hij komt tot
x = 121
y = 2

k wou dat ik er iets van snapte, gvd
Zeg dat dan in plaats van te impliceren dat ie altijd op 12 kapot gaat... :/

Ik zal je 1 tip geven: een programma knalt altijd nadat er iets is misgegaan, niet ervoor. Oftewel, als ie soms op 12 knalt en soms op 28 en soms op 25 is er vrijwel zeker niets aan de hand met 12, 25 of 28 maar met de omgeving. In dit exacte geval gok ik op een zwaar potje heap corruption voordat je deze functie aanroept. Of knalt ie soms ook pas als je 'm voor de 2e keer aanroept oid?

Professionele website nodig?


  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 20:01
moet k dan iets met malloc of heapfree doen :?

k heb t programma alleen maar proberen te porten vanaf VB, omdat t sneller is. verder doe ik nie veel met c/c++, sorry dat k er nie veel van snap

[ Voor 177% gewijzigd door Super_ik op 21-04-2004 16:55 ]

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • Super_ik
  • Registratie: Maart 2001
  • Laatst online: 20:01
k heb een try {} catch {} om heel de functie gezet, maar hij klapt er nog steeds gewoon uit, hij catcht nix :?

8<------------------------------------------------------------------------------------
Als ik zo door ga haal ik m'n dood niet. | ik hou van goeie muziek


  • bramseltje
  • Registratie: September 2001
  • Laatst online: 23-05 10:13
• Ik weet niet precies hoe je met je geheugenmanagement werkt, maar het is verstandig om als je met new werkt ook met delete te werken. Als je dat niet doet, zeker met arrays van dit formaat, raakt je heap snel gefragmenteerd, en je stack ook best snel vol.

• Om problemen te voorkomen en zeker te weten dat je op de goede adressen bezig bent is het misschien een idee om van te voren (dus in je aanroepende functie) de array met gemiddelden aan te maken, en die als reference parameter mee te geven.

Je functie header wordt dan (denk ik) zoiets:
C++:
1
void (unsigned char ** pixels, unsigned int width, unsigned int height, unsigned char& **average);

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 25-05 20:56
Bramseltje schreef op 22 april 2004 @ 17:38:
• Ik weet niet precies hoe je met je geheugenmanagement werkt, maar het is verstandig om als je met new werkt ook met delete te werken. Als je dat niet doet, zeker met arrays van dit formaat, raakt je heap snel gefragmenteerd, en je stack ook best snel vol.
Gefragmenteerde heap? Volle stack? Dat heeft er niets mee te maken! (En bovendien heeft het niets te maken met het gebruik van 'delete' an sich.)
• Om problemen te voorkomen en zeker te weten dat je op de goede adressen bezig bent is het misschien een idee om van te voren (dus in je aanroepende functie) de array met gemiddelden aan te maken, en die als reference parameter mee te geven.
Dat is wel een goede suggestie (al heeft het ook niet zoveel met het probleem dat aan de orde is te maken) maar de functiedeclaratie die je geeft klopt niet; je declareert 'average' als een pointer naar een pointer naar een reference naar een char, terwijl je een reference naar een pointer naar een char wilt hebben. Zoiets dus:
C++:
1
2
3
4
5
void average(
    unsigned char** pixels,
    unsigned int width,
    unsigned int height,
    unsigned char** &result );

  • bramseltje
  • Registratie: September 2001
  • Laatst online: 23-05 10:13
Dat laatste was ik inderdaad ook al achter gekomen. Zat ff wat te figulieren in borland en dat was wel het eerste waar ie over ging klagen...

B) ben nu eenmaal niet zo'n c++ guru ;)

Dat eerste blijkt inderdaad niet van toepassing te zijn omdat het programma al meteen bij het begin op z'n moel gaat.

Maar wanneer je onbeperkt nieuwe arrays in je geheugen gaat plakken raakt de toegewezen ruimte toch op een gegeven moment vol, en zal new toch geen gaatje kunnen vinden voor je nieuwe array?

Hmm, zal het wel verkeerd onthouden hebben dan... Ben dan ook meer op m'n best als ik lekker fout kan programmeren en niet hoef te doen wat leraren ofzo graag willen :D Gewoon wat brute oplossingen bedenken...
offtopic:
Nieuwe thread starten met de memberfunctie van een klasse in MFC bijvoorbeeld...
Nee, microsoft is goed bezig... :D

Verwijderd

Super_ik schreef op 22 april 2004 @ 17:00:
k heb een try {} catch {} om heel de functie gezet, maar hij klapt er nog steeds gewoon uit, hij catcht nix :?
Een access violation betekent dat je buiten een voor schrijven gereserveerd geheugengebied schrijft; dat kan door b.v. voorbij de gootst mogelijke index van een array te schrijven of door naar een ongeinitialiseerde pointer te schrijven, beide kun je in C++ niet afvangen met een try catch constructie.

Weet je wel heel zeker dat de fout in je functie zit en niet net erbuiten? M.a.w. assign je die unsigned char ** die de functie returnt niet verkeerd?

C++:
1
unsigned char blur[800][600]= avarage(screen, 800, 600);
Als je iets vergelijkbaars gedaan hebt is het niet vreemd dat je access violations krijgt.

edit:
Als je wilt debuggen met std::streams dan moet je je output-regels afsluiten met << std::endl of << std::flush (en dus niet alleen met << "...\n"); anders weet je nooit zeker of je output wel naar het beeldscherm/de logfile geflusht is voor je programma crasht!!

edit 2:
tussen regel 28 en 27 heb ik
cout << x << " " << y << '\n'; gezet
Dit bedoel ik dus, verander dat eens in:
C++:
1
cout << x << ' ' << y << endl;
en debug nog eens?

[ Voor 39% gewijzigd door Verwijderd op 22-04-2004 19:13 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 25-05 20:56
Je kunt de exceptions van Windows (beter bekend als SEH, voor Structured Exception Handling) wel catchen, maar dan niet met hetzelfde mechanisme als C++ exceptions. Sowieso moet je in de handler voor een access violation daadwerkelijk de oorzaak ervan wegnemen voordat je programma verder kan gaan; simpelweg de exception catchen en er verder niets mee doen werkt dus nooit.

In dit geval heb je weinig aan een exception handler. Je kunt beter je code aanpassen zodat die goed werkt.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
Als je programma op verschillende plekken crashed, zit je probleem waarschijnlijk niet in deze functie, maar in een functie die je stack trashed door een lokale of globale var te overschrijven.

Zoek eens naar een functie die een lokale variabele ( mn arrays ) heeft en controleer of hij er niet buiten schrijft.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Eh, een AV in Wiindows kun je wel vangen met een catch(...), je kunt alleen niet zeker weten wat er precies waar fout ging.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 25-05 20:56
Als ik dit compileer (met MinGW/GCC 3.2) dan crasht m'n applicatie toch echt (in plaats van netjes af te sluiten, wat zou gebeuren als ik de access violation zou opvangen).
C++:
1
2
3
4
5
6
7
8
9
int main()
{
    int *foo = reinterpret_cast<int*>(-1);
    try {
        return *foo;
    } catch(...) {
        return 0;    
    }
}

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

MSalters schreef op 22 april 2004 @ 23:57:
Eh, een AV in Wiindows kun je wel vangen met een catch(...), je kunt alleen niet zeker weten wat er precies waar fout ging.
Nee, een access violation gaat via het niet C++ compatible SEH mechanisme. Je moet via _set_se_translator een Structured Exception Translator registreren die de exception herkent en vervolgens handmatig een C++ exception opgooit.

Voorbeeldcode, even ranzig snel adapted van wat complete code:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  #include <windows.h>
  #include <eh.h>

  struct AccessViolation {};

  void ExceptionHandler(unsigned int p_Code, 
                                EXCEPTION_POINTERS* p_Exception)
  {
  // Ignore regular C++ exceptions and CTRL-C
  if(p_Code == 0xe06d7363 || p_Code == CONTROL_C_EXIT)
    return;

  switch(p_Code)
    {
    case EXCEPTION_ACCESS_VIOLATION: 
      // p_Exception->ExceptionRecord->ExceptionInformation[0] 
      // is true als het een 'schrijf' exceptie was, en element 1 bevat het adres
      throw AccessViolation;
    default:
      // Ignore....
      return;
    }
  }

  int main()
  {
  _set_se_translator(ExceptionHandler);
  try
    {
    *((int*)(-1)) = -1;
    }
  catch(AccessViolation &)
    {
    cout << "Access Violation!" << endl;
    }
  }

Die 0xe06d7363 is trouwens een 'magic number' waar nergens geen definitie voor bestaat (zelfs niet in nt.h oid), maar da's dus een C++ exception onder Windows SEH :P

[ Voor 57% gewijzigd door curry684 op 23-04-2004 00:54 ]

Professionele website nodig?


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 25-05 20:56
Is dit Visual C++-specifieke code, of doen alle C++ compilers het op deze manier?

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Soultaker schreef op 23 april 2004 @ 01:02:
Is dit Visual C++-specifieke code, of doen alle C++ compilers het op deze manier?
_set_se_translator is Win32-specific. Deze code heb ik gebruikt onder BCB en VC6 en 7.x.

Professionele website nodig?


  • schoene
  • Registratie: Maart 2003
  • Laatst online: 22-05 12:29
Waarom staat die if statement daar eigenlijk? Dit wordt toch al in de switch behandeld?

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
  if(p_Code == 0xe06d7363 || p_Code == CONTROL_C_EXIT)
    return;

  switch(p_Code)
    {
    case EXCEPTION_ACCESS_VIOLATION: 
      // p_Exception->ExceptionRecord->ExceptionInformation[0] 
      // is true als het een 'schrijf' exceptie was, en element 1 bevat het adres
      throw AccessViolation;
    default:
      // Ignore....
      return;
    } 

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

schoene schreef op 23 april 2004 @ 08:46:
Waarom staat die if statement daar eigenlijk? Dit wordt toch al in de switch behandeld?
Zoals gezegd was het quickly adapted code :) In de originele code was de switch tig keer groter en bevatte the default een throw UnknownSystemException oid. Daarnaast heb je een recursief probleem als je C++ exceptions niet expliciet uitsluit, omdat een throw in deze translator zichzelf zal aanroepen (hoor ik iemand stack overflow zeggen? ;) )

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
curry684 schreef op 23 april 2004 @ 00:44:
[...]
Nee, een access violation gaat via het niet C++ compatible SEH mechanisme.
Heb je het getest? Ik dus wel. In VC++ wordt een Access Violation SE gevangen door een catch(...).
code:
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
int main()
{
    try{
        *((int*)0)=0;
    }
    catch(...)
    {
        std::cout << "Zie je wel" <<std::endl;
    }
}

Dit is inderdaad VC++-specifiek. gcc reageert anders op SegFaults. Het is allebei legaal, want de code in kwestie ertoont undefined behavior.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

MSalters schreef op 23 april 2004 @ 10:08:
[...]

Heb je het getest? Ik dus wel.
Maar met de SE Translator is het dus wel compiler-independent en typesafe wat betreft de specifieke exception :)

valt me tegen dat ik dat argument tegen jou of all people open moet trekken :+

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Je hebt helemaal gelijk, maar ik heb ook nooit gezegd dat het verstandig was. Ik reageerde alleen op de claim dat catch niets ving, en de (impliciete) conclusie dat er dus geen Access Violation was.

Die SE Translator is dus ook geen verstandig idee. Een AV moet je oplossen, niet afhandelen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

MSalters schreef op 23 april 2004 @ 13:54:
Je hebt helemaal gelijk, maar ik heb ook nooit gezegd dat het verstandig was. Ik reageerde alleen op de claim dat catch niets ving, en de (impliciete) conclusie dat er dus geen Access Violation was.
Als non-windows man ging ik er van uit dat een AV niet te catchen is (andere OSsen handelen dat b.v. af via een interrupt), ik probeerde helemaal niet te impliceren dat er geen AV optrad :)
Die SE Translator is dus ook geen verstandig idee. Een AV moet je oplossen, niet afhandelen.
Inderdaad, het enige nut is zo ongeveer de mogelijkheid om een automatische dump/stacktrace te genereren.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
Verwijderd schreef op 23 april 2004 @ 14:08:
nderdaad, het enige nut is zo ongeveer de mogelijkheid om een automatische dump/stacktrace te genereren.
Die constructie heeft mij iig geholpen om een hele vervelende av op te sporen. In 'echte' code mag je em in principe niet nodig hebben vind ik.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

MSalters schreef op 23 april 2004 @ 13:54:
Die SE Translator is dus ook geen verstandig idee. Een AV moet je oplossen, niet afhandelen.
Dat is gewoon een waarheid als een koe :)
farlane schreef op 23 april 2004 @ 14:13:
[...]
Die constructie heeft mij iig geholpen om een hele vervelende av op te sporen. In 'echte' code mag je em in principe niet nodig hebben vind ik.
Ik gooi zelf liever een relatief nette exception in het geval van een bug oid dan dat ik een programma opblaas. En bovendien houdt ik wel van exception mechanismes die automatisch stack traces dumpen, en dat doen ze bij mij ook indien er een AV of div-by-zero gebeurt oid ;)

Professionele website nodig?


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
curry684 schreef op 23 april 2004 @ 15:25:
Ik gooi zelf liever een relatief nette exception in het geval van een bug oid dan dat ik een programma opblaas. En bovendien houdt ik wel van exception mechanismes die automatisch stack traces dumpen, en dat doen ze bij mij ook indien er een AV of div-by-zero gebeurt oid ;)
Is idd netter, maar heb je die dan om je main( ... ) zitten, of ga je in elke routine die wel eens een av zou kunnen gooien een av exception handler schrijven ? Die laatste optie lijkt me nogal bewerkelijk namelijk.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

farlane schreef op 23 april 2004 @ 16:14:
[...]


Is idd netter, maar heb je die dan om je main( ... ) zitten, of ga je in elke routine die wel eens een av zou kunnen gooien een av exception handler schrijven ? Die laatste optie lijkt me nogal bewerkelijk namelijk.
Ik heb sowieso in de main app loop en main thread routines altijd een catch-handler voor de root-exception-class, en catch desnoods op een hoger niveau indien de situatie dat vereist. Zodra je een AV gaat expecten ben je hoe dan ook fout bezig, dus die moet je zelden hoeven catchen op een hoger niveau dan dat.

Professionele website nodig?


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 22-05 16:53
curry684 schreef op 23 april 2004 @ 16:16:
[...]

Ik heb sowieso in de main app loop en main thread routines altijd een catch-handler voor de root-exception-class, en catch desnoods op een hoger niveau indien de situatie dat vereist. Zodra je een AV gaat expecten ben je hoe dan ook fout bezig, dus die moet je zelden hoeven catchen op een hoger niveau dan dat.
Mee eens, maar als je het ding in main catched wordt het dumpen van een call stack lastig volgens mij, die is al helemaal gerewind op dat moment.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Verwijderd

farlane schreef op 23 april 2004 @ 17:03:
Mee eens, maar als je het ding in main catched wordt het dumpen van een call stack lastig volgens mij, die is al helemaal gerewind op dat moment.
Ik neem aan dat hij de trace produceert in zijn primaire handler (ExceptionHandler() in zijn voorbeeld) waarna hij de C++ exception gooit en er stack unwinding plaatsvindt.

edit:
Overigens betekent het experiment van MSalters samen met het gegeven dat Super_ik een try catch om die functie heeft gezet wel dat we nu absoluut zeker weten dat de functie zelf geen AV veroorzaakt.

[ Voor 22% gewijzigd door Verwijderd op 23-04-2004 17:36 ]


  • _Squatt_
  • Registratie: Oktober 2000
  • Niet online
Verwijderd schreef op 23 april 2004 @ 17:25:
Overigens betekent het experiment van MSalters samen met het gegeven dat Super_ik een try catch om die functie heeft gezet wel dat we nu absoluut zeker weten dat de functie zelf geen AV veroorzaakt.
Het voorbeeld van MSalters werkt alleen in VC++, Super_ik gebruikt Borland 5.01.

"He took a duck in the face at two hundred and fifty knots."


Verwijderd

_Squatt_ schreef op 23 april 2004 @ 18:43:
Het voorbeeld van MSalters werkt alleen in VC++, Super_ik gebruikt Borland 5.01.
/me zucht :z

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 15:56

.oisyn

Moderator Devschuur®

Demotivational Speaker

curry684 schreef op 23 april 2004 @ 09:12:
Daarnaast heb je een recursief probleem als je C++ exceptions niet expliciet uitsluit, omdat een throw in deze translator zichzelf zal aanroepen (hoor ik iemand stack overflow zeggen? ;) )
Wat ik overigens nogal raar vind als ik de beschrijving lees in de MSDN over _set_se_translator
The _set_se_translator function provides a way to handle Win32 exceptions (C structured exceptions) as C++ typed exceptions. To allow each C exception to be handled by a C++ catch handler, first define a C exception wrapper class that can be used, or derived from, to attribute a specific class type to a C exception. To use this class, install a custom C exception translator function that is called by the internal exception-handling mechanism each time a C exception is raised. Within your translator function, you can throw any typed exception that can be caught by a matching C++ catch handler.
Hieruit maak ik niet op dat je expliciet moet testen voor die code voor C++ exceptions. Logisch ook, want dat is undocumented :). Maar ook het stukje voorbeeldcode dat erbij staat vangt het niet expliciet af. Ik heb het even geprobeerd, en het werkt prima zonder die check. SE's gaan door de translator, C++ exceptions niet...

Maar ik weet dat jij in die handler ook stackdumps maakte van gewone C++ exceptions... hoe werkte dat dan :?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1