Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[C++] Stack overflow big arrays

Pagina: 1
Acties:

Verwijderd

Topicstarter
Als ik in Visual studio 2005 een grote 2 dimensionele array ingeef, dan krijg ik een stack-overflow.

vb.
code:
1
int x[1000][1000];

Dan compileert mijn programma, maar krijg ik volgende fout bij het uitvoeren:
Unhandled exception at 0x004162b7 in test.exe: 0xC00000FD: Stack overflow.

Toen ik nog Visual studio 6.0 gebruikte lukte dit wel nog.

Is er dus een mogelijkheid om (ev. adhv andere compiler settings) toch grote arrays te declareren in VS2005?

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
Erg vreemd, ik heb zelf geen C++ 2005 geinstalleerd, maar C# in Visual Studio 2005 Express kan in ieder geval prima werken met een int array 1000,1000 pas bij x = new int[100000, 100000];
krijg ik een out of memory exception.

Natuurlijk zit C++ nogal anders in elkaar. maar ik wilde het toch even testen, misschien dat je er wat aan hebt :)

~ Mijn prog blog!


  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 21:19

Onbekend

...

Zit het probleem direct in een regel? Of ga je daarna met de inhoud van die cellen rekenen?
Je zou hoogstens een toegangs-of memory probleem moeten krijgen zoals hierboven is beschreven.

Edit:
Ik zie dat je de variable x gebruikt. Is die variable wel uniek en is het niet een x-locatie?

[ Voor 21% gewijzigd door Onbekend op 09-03-2008 17:36 ]

Speel ook Balls Connect en Repeat


Verwijderd

Stack size in VC++ is 1 MB (zie http://msdn2.microsoft.co...rary/tdkhxaks(VS.71).aspx). Je kunt de stack size verbreden of de array op the heap alloceren (int * inplaats van int[][]).

Verder, C# zal dit probleem niet hebben; C# alloceert een array altijd op de heap. Als je in C# een array op de stack wilt hebben, dan moet je custom unsafe code schrijven. En in dat geval zul je ongetwijfeld een stack overflow exception krijgen.

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 19-11 18:15

Sebazzz

3dp

Het probleem komt ook voor in Visual C++ 2008 Professional. Maar alleen in debug mode, niet in release mode.

code:
1
2
3
4
5
; Find next lower page and probe
cs20:
        sub     eax, _PAGESIZE_         ; decrease by PAGESIZE
        test    dword ptr [eax],eax     ; probe page. <-- hier loopt ie vast volgens VC++
        jmp     short cs10

C++:
1
2
3
4
5
6
7
8
9
10
11
12
int _tmain(int argc, _TCHAR* argv[])
{
    try {
        int x[1000][1000];
        cout << "Gelukt";
    }
    catch (char c) {
        cout << "Mislukt";
    }
    cin.get();
    return 0;
}

In de debug build geeft hij oneindig veel fouten over access violations, maar in release mode doet ie het gewoon en zegt hij niets meer dan 'Gelukt'.

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Verwijderd

Topicstarter
Onbekend schreef op zondag 09 maart 2008 @ 17:35:

Zit het probleem direct in een regel? Of ga je daarna met de inhoud van die cellen rekenen?
Je zou hoogstens een toegangs-of memory probleem moeten krijgen zoals hierboven is beschreven.

Edit:
Ik zie dat je de variable x gebruikt. Is die variable wel uniek en is het niet een x-locatie?
Het probleem zit direct in die regel, dus waarschijnlijk problemen met het reserveren van dit geheugen.

De variabele naam 'x' is maar een voorbeeld, hetzelfde probleem treedt op met een andere naam.
Verwijderd schreef op zondag 09 maart 2008 @ 17:35:

Stack size in VC++ is 1 MB (zie http://msdn2.microsoft.co...rary/tdkhxaks(VS.71).aspx). Je kunt de stack size verbreden of de array op the heap alloceren (int * inplaats van int[][]).

Verder, C# zal dit probleem niet hebben; C# alloceert een array altijd op de heap. Als je in C# een array op de stack wilt hebben, dan moet je custom unsafe code schrijven. En in dat geval zul je ongetwijfeld een stack overflow exception krijgen.
Ik probeerde in de project properties (config properties/linker/system) de stack reserve en stack commit size te vergroten. Er staat wel geen eenheid bij (bit, byte, Mb,?) Ik plaatste er 1000000, maar krijg nog steeds dezelfde foutmelding.

Kun je wat meer uitleg geven over hoe je op the heap alloceert?

  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 21:19

Onbekend

...

Gevonden op internet:
But really you should use dynamic allocation, any of the methods I suggested
in response to your last post would be prefereable to trying to declare such
a huge array on the stack.

For instance

#include <vector>

std::vector<std::vector<double> > array(500);
for (int i = 0; i < 500; ++i)
array[i].resize(500);

is a simple way to give you a 500 by 500 2D array without blowing your
stack.
Waarschijnlijk wordt die complete array meegegeven die uiteindelijk op de stack belandt.
Probeer eens uit zou ik zeggen. :)

Speel ook Balls Connect en Repeat


  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 01-11 22:03

leuk_he

1. Controleer de kabel!

Verwijderd schreef op zondag 09 maart 2008 @ 18:18:
Ik probeerde in de project properties (config properties/linker/system) de stack reserve en stack commit size te vergroten. Er staat wel geen eenheid bij (bit, byte, Mb,?) Ik plaatste er 1000000, maar krijg nog steeds dezelfde foutmelding.

Kun je wat meer uitleg geven over hoe je op the heap alloceert?
Voorbeeld code van sebaz werkt bij mij wel hoor:

Afbeeldingslocatie: http://leuk.seeding.it/images/stacksize.PNG

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Ik wou eerst zeggen dat het wellicht geen goed idee is om zo'n megastuk geheugen op de stack te allocaten, maar ik bedenk met net dat het wellicht een performance voordeel heeft: je hebt geen overhead voor je new/delete calls die je anders zou hebben (immers, je doet alleen je ebp veranderen, of je dat nou met een klein beetje of met 4 MB doet, boeit niks). Correct me if I'm wrong :)

Desondanks is het natuurlijk goed mogelijk, en waarschijnlijk aan te raden om gewoon een new/delete te doen, al is het alleen maar om te checken of die hoeveelheid geheugen wel beschikbaar is. (NATUURLIJK, je moet eigenlijk elke new/malloc etc. de return value checken, maar goed...)

-niks-


  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 19-11 18:15

Sebazzz

3dp

leuk_he schreef op zondag 09 maart 2008 @ 20:00:
[...]


Voorbeeld code van sebaz werkt bij mij wel hoor:

[afbeelding]
Wat voor geheugengebruik krijg je?

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 01-11 22:03

leuk_he

1. Controleer de kabel!

Sebazzz schreef op zondag 09 maart 2008 @ 20:38:
[...]
Wat voor geheugengebruik krijg je?
In mijn task manager zegt hij 5400Kb max gebruikt te hebben. Maar eigenlijk weet ik niet goed hoe je geheugen gebruik van een appiclatie kunt zien (Met name waaraan het gebruikt wordt in een grote applicatie) .


Maar hij verbruikt dus niet meteen 32 Meg?

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20:02
MLM schreef op zondag 09 maart 2008 @ 20:11:
Ik wou eerst zeggen dat het wellicht geen goed idee is om zo'n megastuk geheugen op de stack te allocaten, maar ik bedenk met net dat het wellicht een performance voordeel heeft: je hebt geen overhead voor je new/delete calls die je anders zou hebben (immers, je doet alleen je ebp veranderen, of je dat nou met een klein beetje of met 4 MB doet, boeit niks).
Aan de andere kant: als je zo'n flink stuk geheugen nodig hebt zal je er ook wel aardig wat gaan rekenen (waar ga je die array anders meer vullen?) dus ten opzichte van het geheel zal de overhead van die allocatie nogal meevallen. Ik zou zulke grote arrays dus niet op de stack alloceren.

  • igmar
  • Registratie: April 2000
  • Laatst online: 06-11 09:18

igmar

ISO20022

Verwijderd schreef op zondag 09 maart 2008 @ 17:08:

vb.
code:
1
int x[1000][1000];

Dan compileert mijn programma, maar krijg ik volgende fout bij het uitvoeren:
Unhandled exception at 0x004162b7 in test.exe: 0xC00000FD: Stack overflow.
Je stack loopt over. Aan de andere kant : als je dit soort dingen doet moet je toch denk ik eens gaan kijken naar malloc(). 4 MB ineens op de stack gooien wijst over het algemeen niet op een goed ontwerp.
Toen ik nog Visual studio 6.0 gebruikte lukte dit wel nog.

Is er dus een mogelijkheid om (ev. adhv andere compiler settings) toch grote arrays te declareren in VS2005?
Waarom zou je ? Bovenstaande kan met malloc() ook, en je bet niet meer afhankelijk van een instelling en/of OS.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
Een andere mogelijkheid is het array static maken, afhankelijk van of je een dynamische grootte nodig hebt of niet.

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.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20:02
Dynamisch arrays alloceren op de stack is officieel niet toegestaan (al zou het kunnen dat MSVC het wel ondersteunt; GCC in ieder geval wel) dus dat kun je ook maar beter laten.

Verder is static maken natuurlijk alleen een optie als je functie niet reentrant hoeft te zijn. Misschien geen probleem, maar netjes is ook anders. Dan kun je die array in principe ook gewoon globaal maken, dan is tenminste duidelijk dat je met een globale array werkt (want dat is het dan eigenlijk).

  • sam.vimes
  • Registratie: Januari 2007
  • Laatst online: 08-06 08:44
Sebazzz schreef op zondag 09 maart 2008 @ 17:49:
<knip>
In de debug build geeft hij oneindig veel fouten over access violations, maar in release mode doet ie het gewoon en zegt hij niets meer dan 'Gelukt'.
Kennelijk staat in de releasemode de stackoverflowcontrole niet aan. Controleer je compilersettings...
Verwijderd schreef op zondag 09 maart 2008 @ 17:08:
Als ik in Visual studio 2005 een grote 2 dimensionele array ingeef, dan krijg ik een stack-overflow.
code:
1
int x[1000][1000];

Dan compileert mijn programma, maar krijg ik volgende fout bij het uitvoeren:
Unhandled exception at 0x004162b7 in test.exe: 0xC00000FD: Stack overflow.
<knip>
Heb je echt precies 1000x1000 elementen nodig? Dit ziet er meer uit als een willekeurige bovengrens die in 99% veel te hoog zal zijn en daardoor meer resources claimt dan nodig is. In de overige 1% gaat je rowcount net over die grens en zit je met een segmentation fault.

Ik zou dynamische allocatie gebruiken zodat precies genoeg geheugen gereserveerd kan worden. Gebruik daarvoor de STL-klasse <vector>.

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-11 18:33
Soultaker schreef op maandag 10 maart 2008 @ 09:57:
Dynamisch arrays alloceren op de stack is officieel niet toegestaan.
Ik doelde eigenlijk ook dynamisch op de heap.
Verder is static maken natuurlijk alleen een optie als je functie niet reentrant hoeft te zijn.
Dat is idd een tweede vereiste.
Misschien geen probleem, maar netjes is ook anders. Dan kun je die array in principe ook gewoon globaal maken, dan is tenminste duidelijk dat je met een globale array werkt (want dat is het dan eigenlijk).
Mja dat ligt een beetje aan de applicatie van de TS, als het ding niet globaal hoeft te zijn zou ik 'em ook niet globaal maken. ( Een variabele static maken zou ik niet slordig willen noemen als het voldoet aan de eisen van de applicatie. )
Als tussenweg heb je nog de mogelijkheid om de variabele static te maken in de scope van de translation unit.

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

Topicstarter
sam.vimes schreef op maandag 10 maart 2008 @ 10:06:
[...]

Heb je echt precies 1000x1000 elementen nodig? Dit ziet er meer uit als een willekeurige bovengrens die in 99% veel te hoog zal zijn en daardoor meer resources claimt dan nodig is. In de overige 1% gaat je rowcount net over die grens en zit je met een segmentation fault.

Ik zou dynamische allocatie gebruiken zodat precies genoeg geheugen gereserveerd kan worden. Gebruik daarvoor de STL-klasse <vector>.
Ik heb inderdaad 1000*1000 elementen nodig. En in het ergste geval nog veel meer. Het gaat om een programma die externe hardware aanstuurt en op véél coordinaten meetpunten moet binnenlezen.
Momenteel schrijf ik direct naar een file. Dit werkt behoorlijk goed.

ik heb nu net een testje gedaan met de STL-klasse vector. Dit zou ook goed kunnen werken voor mij.
Alvast bedankt voor de reacties.
Pagina: 1