Algemene manier van oplossen Fout: stapel rond de variabele ‘x’ was beschadigd

Ik heb een programma dat me de fout in VS2010 aanzet, in Debug:

Error: Stack around the variable 'x' was corrupted

Dit geeft me de functie waar een stapel overstroomt, waarschijnlijk optreedt, maar ik kan niet visueel zien waar het probleem is.

Is er een algemene manier om deze fout met VS2010 te debuggen? Zou het mogelijk zijn om in te stellen welke schrijfbewerking het onjuiste stapelgeheugen overschrijdt?
bedankt


Antwoord 1, Autoriteit 100%

Is er een algemene manier om deze fout te debuggen met VS2010?

Nee, dat is er niet. Wat je hebt gedaan is om een ​​op de een of andere manier ongedefinieerd gedrag aan te roepen. De reden dat deze gedragingen niet gedefinieerd zijn, is dat de algemene zaak erg moeilijk is om te detecteren / diagnosticeren. Soms is het nuttig onmogelijk om dit te doen.

Er zijn echter een enigszins klein aantal dingen die doorgaans uw probleem veroorzaken:

  • onjuiste behandeling van geheugen:
    • iets twee keer verwijderen,
    • Gebruik van het verkeerde type deletie (freevoor iets dat is toegewezen met new, ENC.),
    • Toegang tot iets nadat het geheugen is verwijderd.
  • die een aanwijzer of verwijzing naar een lokaal retourneren.
  • lezen of schrijven langs het einde van een array.

Antwoord 2, Autoriteit 57%

Dit kan worden veroorzaakt door verschillende problemen, die over het algemeen moeilijk zijn om te zien:

  • Dubbels verwijderen
  • deleteEen variabele die is toegewezen met new[]of delete[]A VARIAIEL GEKOCHT MET new
  • deleteiets dat is toegewezen met malloc
  • deleteEen automatische opslagvariabele
  • die een lokale door verwijzing retourneert

Als het niet meteen duidelijk is, zou ik mijn handen op een geheugendebugger krijgen (ik kan bedenken aan rationele zuivering voor Windows).


Antwoord 3, Autoriteit 21%

Dit bericht kan ook te wijten zijn aan een arraygrens-overtreding. Zorg ervoor dat uw functie (en elke functie die het oproept, in het bijzonder lidfuncties voor op stapel gebaseerde objecten) aan de grenzen van alle arrays die kan worden gebruikt.


Antwoord 4, Autoriteit 21%

Eigenlijk is wat u ziet is vrij informatief, moet u inchecken in de buurt van X-variabele locatie voor elke activiteit die deze fout kan veroorzaken.

Hieronder is hoe u een dergelijke uitzondering kunt reproduceren:

int main() {
    char buffer1[10];
    char buffer2[20];
    memset(buffer1, 0, sizeof(buffer1) + 1);
    return 0;
}

genereert (VS2010):

RUND-TIME CONTROLEER FAU # 2 – Stapel rond de variabele ‘buffer1’ is beschadigd.

Natuurlijk heeft Memet 1 Char More geschreven dan het zou moeten zijn. Vs met optie \ GS maakt het mogelijk om dergelijke bufferoverloop te detecteren (die u hebt ingeschakeld), voor meer informatie hier: http://msdn.microsoft.com/en-us/library/aA290051 .

U kunt bijvoorbeeld debugeer en stap door uw code gebruiken, telkens kijken naar inhoud van uw variabele, hoe ze veranderen. Je kunt ook proberen geluk met data breakpoints, je instelt Breakpoint wanneer sommige geheugenlocatie verandert en debugger op dat moment stopt, eventueel je callstack laten zien waar het probleem zich bevindt. Maar dit werkt misschien niet met \ GS-vlag.

Voor het detecteren van heap Overflows kunt u GFLAGS-tool gebruiken.


Antwoord 5, Autoriteit 14%

Ik was al uren verbaasd door deze fout, ik ken de mogelijke oorzaken en ze worden al vermeld in de vorige antwoorden, maar ik wijs geen geheugen toe, geen toegang tot array-elementen, niet terug naar lokaal Variabelen …

Ten eindelijk de bron van het probleem gevonden:

*x++;

De intentie was om de puntige waarde te verhogen. Maar als gevolg van de precedentie ++komt eerst, het verplaatsen van de xPOSER POSER FORWARD DAN DAN *doet niets, vervolgens op *xzal de stapel kanarie beschadigd zijn als de parameter van de stapel komt, waardoor vs klagen.

Het wijzigen van (*x)++lost het probleem op.

Ik hoop dat dit helpt.


Antwoord 6

Hier is wat ik in deze situatie doe:

Stel een breekpunt in op een locatie waar u de (juiste) waarde van de variabele in kwestie kunt zien, maar voordat de fout gebeurt. U hebt het geheugenadres van de variabele nodig waarvan de stapel is beschadigd. Soms moet ik een regel code toevoegen om de debugger te geven om me gemakkelijk het adres te geven (int * x = & amp; y)

Op dit moment kunt u een geheugenbrekerpunt instellen (Debug- & GT; nieuwe breekpoint- & gt; nieuwe gegevens breekpunt)

Hit Play en de debugger moet stoppen wanneer het geheugen is geschreven. Kijk de stapel op (de mijne breekt meestal in een montagecode) om te zien wat er wordt gebeld.


Antwoord 7

Ik volg meestal de variabele vóór de klagende variabele die me meestal helpt het probleem te krijgen. Maar dit kan ooit erg complex zijn zonder aanwijzing zoals je het hebt gezien. U kunt debuggenmenu & GT; & GT mogelijk maken; Uitzonderingen en vink de ‘Win32-uitzonderingen’ aan om alle uitzonderingen te vangen. Dit zal deze uitzonderingen nog steeds niet vangen, maar het kan iets anders vangen dat indirect naar het probleem kan wijzen.

In mijn geval werd het veroorzaakt door de bibliotheek die ik gebruikte. Het bleek dat het headerbestand dat ik in mijn project had opgenomen niet helemaal overeenkwam met het eigenlijke headerbestand in die bibliotheek (met één regel).

Er is een andere fout die ook gerelateerd is:

0xC015000F: De activeringscontext die wordt gedeactiveerd is niet de meest
onlangs geactiveerde.

Toen ik het beu was om het mysterieuze bericht met beschadigde stapel op mijn computer te krijgen zonder foutopsporingsinformatie, probeerde ik mijn project op een andere computer en in plaats daarvan kreeg ik het bovenstaande bericht. Met de nieuwe uitzondering kon ik mijn weg naar buiten werken.


Antwoord 8

Ik kwam dit tegen toen ik een pointer-array van 13 items maakte en vervolgens het 14e item probeerde in te stellen. Het wijzigen van de array naar 14 items loste het probleem op. Ik hoop dat dit sommige mensen helpt ^_^


Antwoord 9

Een relatief veel voorkomende oorzaak van het probleem “Stack around the variable ‘x’ was corrupted” is verkeerd casten. Het is soms moeilijk te herkennen. Hier is een voorbeeld van een functie waarbij een dergelijk probleem optreedt en de oplossing. In de functie assignValuewil ik een waarde toekennen aan een variabele. De variabele bevindt zich op het geheugenadres dat als argument aan de functie is doorgegeven:

using namespace std;
template<typename T>
void assignValue(uint64_t address, T value)
{
    int8_t* begin_object = reinterpret_cast<int8_t*>(std::addressof(value));
    // wrongly casted to (int*), produces the error (sizeof(int) == 4)
    //std::copy(begin_object, begin_object + sizeof(T), (int*)address);  
    // correct cast to (int8_t*), assignment byte by byte, (sizeof(int8_t) == 1)
    std::copy(begin_object, begin_object + sizeof(T), (int8_t*)address); 
}
int main()
{
    int x = 1;
    int x2 = 22;
    assignValue<int>((uint64_t)&x, x2);
    assert(x == x2);
}

Other episodes