Hvorfor min c ++ kode kører på Linux, men ikke på Windows, er der et problem med RAM-hukommelse?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg er ny programmering, og jeg har fundet et problem
Jeg definerer et c ++ array som dette


double name[512][512]


Men når jeg kører det på Windows (det kompilerer uden fejl) det styrter. Når jeg kører på Linux (Ubuntu) kører det, hvordan det skal gøre det uden problemer. Jeg tror, ​​at Windows begrænser hukommelsen, mit program kan tage, har jeg ret? Hvordan kan jeg løse det? Tak til alle, der kan give mig en hånd.

Bedste reference


Jeg 'm gætter (siden du ikke har angivet en MCVE), at din name array er en automatisk variabel, så den bliver allokeret på opkaldsstakken. [21] [22]


BTW er problemet ikke i RAM'et (som styres af operativsystemet; brugerrumsprogrammer bruger ikke direkte RAM men virtuel hukommelse), men i den virtuelle adresse space (dets stakke segment) af din proces. På Linux kan du bruge /proc/ (se proc (5) og pmap (1)) for at forespørge din proces 'virtuelt adresserum. Og læs Operativsystemer: Tre enkle stykker for at forstå OS'ens rolle. [23] [24] [25] [26] [27] [28] [29] [30]


Bemærk at på x86-64 sizeof(name) sandsynligvis er 2097152 bytes.


Opkaldsstakken er begrænset i størrelse . På Linux er den sædvanlige grænse 4 eller 8 megabyte (men der er en måde at ændre den på) det er rygter om at være 1 megabyte på Windows. Du har en stabel overløb. [31]


Du er sandsynligvis over denne grænse. Overvej at bruge en vis dynamisk hukommelsesallokering (f.eks. Med new, men ved at bruge højere C ++-konstruktioner som beholdere og smarte peger bør du generelt undgå at bruge det eksplicit. De fleste C + + standardbeholdere, især std::vector (men ikke std::array) bruger det (bunken) til interne data. [32] [33] [34] [35] [36] [37]


Som en tommelfingerregel skal hver opkaldsramme være ret lille (fx kilobytes).


Og kompilatoren kunne have advaret dig, hvis du kompilerer med g++ -Wall -Wextra -Wstack-usage=1500 -g på Linux. Lær også at bruge debuggeren gdb. Vær bange for udefineret adfærd. [38] [39] [41]


Du kan også bruge noget ekstra bibliotek som Boost (eller noget andet), der giver matrixer, eller har din egen Matrix abstrakte datatype (som ville hæve allokere sine data). Vær opmærksom på reglen om 5 [42] [43] [44] [45]


Tag flere uger til at læse nogle gode C ++ programmeringsbøger, men vær opmærksom på, at C ++ er et meget vanskeligt og komplekst programmeringssprog (læs også SICP for at lære mere generelle programmeringskoncepter og spille med nogle Scheme implementeringer som f.eks. ketcher). Senere kan du læse en bog om garbage collection (begreberne der er relevante for hukommelsesstyring). [46] [47] [48] [49] [50] [51]]] [52]

Andre referencer 1


Du rammer rammestrømme.


sizeof(double) er 8 på Windows.


Således er 8*512*512 2MB. Hvis jeg ikke tager fejl, er standardstørrelsen for Visual Studio-kompilatoren 1 MB. STACK compiler-knappen på linkeren kan bruges til at øge denne størrelse. [53]


Som andre sandsynligvis vil påpege, for store arrays, brug heapen (malloc/new, free/delete) i stedet for at optage store mængder stak med array variabler.

Andre referencer 2


Du forsøger sandsynligvis at allokere arrayet på stakken, og stakken er mindre på Windows-systemet. Hvis det er tilfældet, gør arrayet globalt eller static, og problemet vil gå væk.


En anden mulighed er at allokere arrayet dynamisk. For eksempel:


struct Array {
    double vals[512][512];
};

// in a function:
auto name\_guard = std::make\_unique<Array>();
auto &name = name\_guard->vals;


Her name\_guard sikrer, at lagringen slettes, når den ikke længere er nødvendig (som bestemt af name\_guard livstid og name har samme betydning som name i spørgsmålet. Bemærk at name må ikke have lov til at overleve beskyttelsesobjektet.