webForumDet fria alternativet

operatorn new - undantag (xalloc) fråga

C/C++ur C/C++

9 svar · 219 visningar · startad av forum

Medlem sedan apr. 2003100 inlägg
Frågan#1

Hej!

Hur ska jag bära mig åt för att fånga upp att det inte finns tillräckligt med minne vid en allokering, om så är fallet.

Så här ser min kod ut:

#include <iostream.h>
#include <stdio.h>
#include <except.h>

class OutOfMemory {};

void main(void)
{
int* myInt;

try

{
myInt = new int(30);
}
catch(xalloc)
{
cout << "Kunde inte reservera minne";
}
getchar();
delete myInt;
}

,,,Men det verkar inte funka. Jag kan, till synes iallafall, allokera minne för hur många intar som helst.

Vad gör jag för fel?

Tacksam för svar.

Medlem sedan okt. 20013 217 inlägg
#2

Som jag ser det så gör new en "throw()" enbart och du försöker fånga nått annat. Prova catch(...) istället.

Medlem sedan juli 2002581 inlägg
#3

Nej, new gör inte en throw;

Det du ska fånga är std::bad_alloc&

#include <new>
int* p;
try
{
  p = new int[1000000000];
}
catch (std::bad_alloc& e)
{
  std:cout << "Allokering misslyckades";
}
Medlem sedan juli 2002581 inlägg
#4

En sak till:

myInt = new int(30);

reserverar *inte* 30 stycken ints, utan en enda som får värdet 30.

Medlem sedan mars 20034 471 inlägg
#5

Jag är ingen stjärna på det här, och har aldrig använt det själv, så ta det med en nypa salt. Men det jag har fått lära mig är följande:

När new misslyckas kastas - enligt default - ett bad_alloc som är subklass till exception. För att kunna fånga det i en catch sats *måste* man ha med
#include <new> //bland det man inkluderar
annars kastas det, men du kan inte fånga det med
catch(bad_alloc &e) {}
Jag *tror* att man måste använda referenser, vet dock inte varför.

(((Sedan: det är väl inte förvånande att du kan skapa godtyckligt många intar? Hur lite minne har du egentligen?!? Idag är det ju oftast svårt att slå i minnestaket och att göra det med små intar borde vara ännu svårare?))) OBS! Föreg. är feltänkt från början till slut!

Medlem sedan juli 2002581 inlägg
#6

aasah skrev:

När new misslyckas kastas - enligt default - ett bad_alloc som är subklass till exception.

Rätt.

aasah skrev:

För att kunna fånga det i en catch sats *måste* man ha med
#include <new> //bland det man inkluderar
annars kastas det, men du kan inte fånga det med
catch(bad_alloc &e) {}

Du kan antingen fånga det som exception eller bad_alloc

aasah skrev:

Jag *tror* att man måste använda referenser, vet dock inte varför.

Man måste inte använda referenser, men det är absolut bäst att göra det, eftersom exception& fångar även underklasser till exception. Då missar man inga fel i onödan.

aasah skrev:

Sedan: det är väl inte förvånande att du kan skapa godtyckligt många intar? Hur lite minne har du egentligen?!? Idag är det ju oftast svårt att slå i minnestaket och att göra det med små intar borde vara ännu svårare?

Det är väl inte svårt? Denna allokering kommer inte att fungera på någon Windows-dator.
int* p = new int[1000000000];

Medlem sedan mars 20034 471 inlägg
#7

Sang-drax skrev:

aasah skrev:

För att kunna fånga det i en catch sats *måste* man ha med
#include <new> //bland det man inkluderar
annars kastas det, men du kan inte fånga det med
catch(bad_alloc &e) {}

Du kan antingen fånga det som exception eller bad_alloc

Visst, men inte utan #include <new>, väl?

Sang-drax skrev:

aasah skrev:

Jag *tror* att man måste använda referenser, vet dock inte varför.

Man måste inte använda referenser, men det är absolut bäst att göra det, eftersom exception& fångar även underklasser till exception. Då missar man inga fel i onödan.

??? Hittar vi fler exceptions med exception& än med exception* ? Skulle vi missa subklasserna om vi fångade in pekare till undantagen i stället? Varför?

Sang-drax skrev:

aasah skrev:

Sedan: det är väl inte förvånande att du kan skapa godtyckligt många intar? Hur lite minne har du egentligen?!? Idag är det ju oftast svårt att slå i minnestaket och att göra det med små intar borde vara ännu svårare?

Det är väl inte svårt? Denna allokering kommer inte att fungera på någon Windows-dator.
int* p = new int[1000000000];

Nej, det är riktigt. Jag tänkte inte längre än min korta näsa när jag skrev det... Sorry!

Medlem sedan juli 2002581 inlägg
#8

aasah skrev:

Visst, men inte utan #include <new>, väl?

Jo då.

#include <iostream>
#include <exception>
int main()
{
    using namespace std;

    try
    {
        int* p = new int[1000000000];
    }
    catch (exception& e)
    {
        cout << "misslyckat: " << e.what() ;
    }
}

Skriver ut
"misslyckat: bad_alloc"

Det är det som är det braiga med OOP och arv.

aasah skrev:

??? Hittar vi fler exceptions med exception& än med exception* ? Skulle vi missa subklasserna om vi fångade in pekare till undantagen i stället? Varför?

Du kan inte fånga pekare till exceptions, endast objektsvis och med referenser.

Medlem sedan juli 2002581 inlägg
#9

Förtydligande:

Man missar ingenting med att fånga som objekt, men jämför dessa två kodsnuttar så förstår du skillnaden:

#include <iostream>
#include <exception>
int main()
{
    using namespace std;

    try
    {
        int* p = new int[1000000000];
    }
    catch (exception& e)
    {
        cout << "misslyckat: " << e.what() ;
    }
}
#include <iostream>
#include <exception>
int main()
{
    using namespace std;

    try
    {
        int* p = new int[1000000000];
    }
    catch (exception e)
    {
        cout << "misslyckat: " << e.what() ;
    }
}
Medlem sedan mars 20034 471 inlägg
#10

Sang-drax skrev:

Förtydligande:

Man missar ingenting med att fånga som objekt, men jämför dessa två kodsnuttar så förstår du skillnaden:...

Nej, naturligtvis vill man inte fånga som objekt.
...

Ååååh, vad man kan vara korkad ibland! Naturligtvis kan man inte fånga ett kastat objekt med en metod som vill ta en pekare till objektet.... :r ÄNTLIGEN! Den insikten tog två år.... :r (I detta specifika fall har jag inte fattat förrän nu att det är det det handlar om... annars brukar man ju kunna välja om man vill köra med referenser eller pekare....) :r

136 ms totalt · 3 externa anrop · v20260731065814-full.b746b907
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
133 ms — hämta tråd, inlägg och bilagor (db)