C++ memory allocation-Fehler ohne Verwendung von new
Ich habe Probleme mit meinem Programm werfen eine große Anzahl von Speicher-Allokation Ausnahmen und ich bin eine sehr harte Zeit der Diagnose des Problems...ich würde post code, aber mein Programm ist sehr groß und ich habe die geschützte Informationen betrifft, so bin ich der Hoffnung etwas Hilfe zu bekommen, ohne Buchung den code. Wenn Sie planen, reagiert mit irgendeiner form von SSCCE Kommentar, jetzt einfach aufhören zu Lesen und speichern Sie uns beide einige Zeit. Dies ist ein Fall, wo ich nicht buchen kann, prägnante code - ich werde versuchen, so klar und prägnant wie möglich mit meiner problem-Beschreibung und einige spezifische Fragen stellen.
Programm Hintergrund - mein Programm ist im Grunde ein Daten-cruncher. Es braucht ein Bündel von Daten Tabellen als Eingänge, führt Berechnungen durch und spuckt neue Daten-Tabellen auf der Grundlage der Berechnungsergebnisse. Alle meine Daten-Strukturen sind benutzerdefinierte Klassen (bestehend aus int, double und string-Typen mit Vektor-Container für arrays). In allen Fällen, die ich initiieren Instanzen der class-Variablen ohne Verwendung von new und delete.
Problem Beschreibung - mein Programm ohne Warnungen kompiliert, und läuft wunderbar auf kleinere Datensätze. Allerdings, wenn ich erhöhen den Datensatz (aus einem 20x80-array 400x80), ich starte wirft bad_alloc Ausnahmen (sobald ich Sie bearbeitet habe die ersten 35 Einträge oder so). Die großen Datenmengen gut läuft in 17 von 18 Module, die ich isoliert haben eine Funktion, wo der Fehler Auftritt. Die Berechnungen benötigt werden für diese Funktion würde das Ergebnis in etwa 30.000 Zeilen an Daten, die erstellt wird, während die anderen Funktionen in meinem code generieren 800,000+ Zeilen ohne Zwischenfälle.
Die einzige wirkliche einzigartiges Attribut in diesem Modul ist, dass ich die Größe einer Menge (etwa 100 mal pro Funktionsaufruf), und dass die Funktion eine rekursive Schleifen während der Größenänderung (die Funktion ist die Zuteilung Quadratmeter aus einem Gebäude ein Mieter zu einem Zeitpunkt, und dann die Aktualisierung der übrigen Füße zugewiesen werden, nach der jeder Mieter Leasing-Größe und-Dauer ist simuliert, bis alle Quadratmeter sind reserviert). Auch der Fehler passiert an fast der gleichen Stelle jeder Zeit (aber nicht die exakt gleichen Ort, weil ich einen random number generator ist, werfen in einigen Variationen zu den Ergebnissen). Was wirklich verwirrt mich ist, dass die ersten ~34 Aufrufe dieser Funktion funktionieren, und die ~35 rufen Sie nicht mehr Speicher benötigen als die bisherigen 34, doch bin ich mit diesen bad_alloc Ausnahmen auf der 35th nennen, dennoch...
Ich weiß, es ist schwer zu helfen ohne code. Bitte versuchen Sie, nur geben Sie mir einige Richtung. Meine konkreten Fragen lauten wie folgt:
-
Wenn ich mich nicht mit "new" und "delete", und alle meine Variablen initialisiert, die INNERHALB der lokalen Funktionen, ist es möglich, Speicherlecks /Zuweisung Probleme durch wiederholte Funktionsaufrufe? Gibt es irgendetwas, was ich tun können oder sollten, um Speicher zu verwalten, bei der Initialisierung Variablen sind lokale Funktion mit "vector-Instanz;" zum deklarieren von Variablen?
-
Gibt es irgendeine chance, ich bin mit niedrigen auf stack-Speicher, wenn mache ich das ganze Programm durch den stack? Ist es möglich, dass ich zum laden brauchen einige meiner großen lookup-Tabellen (maps, usw.) auf dem heap, und dann verwenden Sie einfach den stack für mein Iterationen, wo die Geschwindigkeit wichtig ist?
-
Gibt es ein problem mit der Größe einer Menge, die den Speicher betreffen? Könnte dies ein Beispiel, wo ich sollte, verwenden Sie "new" und "delete" (ich habe davor gewarnt, die in vielen Fällen nicht, diese zu benutzen, es sei denn, es gibt einen sehr starken, speziellen Grund, dies zu tun)?
-
[Im Zusammenhang mit der 3] Innerhalb der problem-Funktion, erstelle ich eine Klasse, variable, dann schreiben Sie über diese variable über 20-mal (einmal für jedes "iteration" von meinem Modell). Ich brauche nicht die Daten aus der vorherigen iteration, wenn ich dies tun...so konnte ich angeblich eine neue Instanz erstellen, der die variable für jeden Durchlauf, aber ich verstehe nicht, wie dies helfen würde, unbedingt (da klar bin ich in der Lage zu tun, alle 20 Iterationen auf eine Instanz, die auf den ersten ~34 Daten-slices)
Irgendwelche Gedanken würde geschätzt werden. Ich kann versuchen, die post-code, aber ich habe schon versucht, dass einmal und jeder schien zu abgelenkt von der Tatsache, dass es nicht kompilierbar. Ich kann nach der Funktion in Frage stellen, aber es wird nicht kompiliert von selbst.
Hier ist die Klasse, die das problem verursacht:
//Class definition
class SpaceBlockRentRoll
{
public:
double RBA;
string Tenant;
int TenantNumber;
double DefaultTenantPD;
int StartMonth;
int EndMonth;
int RentPSF;
vector<double> OccupancyVector;
vector<double> RentVector;
};
//Class variable declaration (occuring inside function)
vector<SpaceBlockRentRoll> RentRoll;
Auch, hier ist ein Ausschnitt aus der Funktion, wo der Rekursion tritt auf,
for (int s=1; s<=NumofPaths; ++s) {
TenantCounter = 0;
RemainingTenantSF = t1SF;
if (RemainingTenantSF > 0) {
while (RemainingTenantSF > 0) {
TenantCounter = TenantCounter + 1;
//Resize relevant RentRoll vectors
ResizeRentRoll(TenantCounter, NumofPaths, NumofPeriods, RentRoll);
//Assign values for current tenant
RentRoll[TenantCounter] = AssignRentRollValues(MP, RR)
//Update the square feet yet to be allocated
RemainingTenantSF = RemainingTenantSF - RentRoll[TenantCounter].RBA;
}
}
}
- Drucken Sie die Größen und die Kapazität der Vektoren. Es könnte sein, dass einige von Ihnen größer als Sie denken.
- Wie aaronman erwähnt, versuchen te reproduzieren Sie Ihr problem in einem kleinen Beispiel. Möchten Sie vielleicht kürzen Sie Ihre Frage auch. Denn ich werde es nicht Lesen.
- Danke für die Anregung, ich werde versuchen, dass.
- Sind Sie vorbei um Zeiger auf Objekte auf dem stack? Das ist keine gute Idee. Im Allgemeinen sollten Sie lernen, wie man den heap, bevor Sie versuchen zu schreiben, die ein Komplexes c++ - Programm.
bad_alloc
ausgelöst durchoperator new
. Da Sie erwähnenresize
ich nehme an, Sie sind mitstd::vector
. Wenn, bin ich richtig in dieser Annahme, auch wenn Sie nichtnew
selbststd::vector
tut. Ich denke, Sie haben eine falsche Vorstellung, dass Ihre Daten auf den stack. Ihrestd::vector
ist auf stack, aber es weist auf heap zum speichern Ihrer Elemente.- Das ist richtig - ich bin mit Vektor (eigentlich eine ganze Menge). Ich bin mit Vektor innerhalb meiner Klasse variable, und dann bin ich erstellen einen Vektor, der die class-variable selbst (siehe kleines code-snippet oben geschrieben meiner Klasse Erklärung). Könnte dies die Ursache für mein problem?
Du musst angemeldet sein, um einen Kommentar abzugeben.
bad_alloc
kommt von heap Probleme irgendwelcher Art, und geworfen werden kann von jedem code, der indirekt zuweist oder freigibt heap-Speicher, die enthält alle standard-Bibliothek Sammlungen (std::vector
,std::map
etc.) sowiestd::string
.Werden, wenn Ihre Programme nicht verwenden eine Menge von heap-Speicher (also sind Sie nicht laufen out-of-heap),
bad_alloc
s sind wahrscheinlich verursacht durch heap-Beschädigung, die in der Regel verursacht durch die Verwendung baumelnden Zeiger in den heap.Du erwähnen, dass dein code nicht viel
resize
Operationen --resize
auf den meisten Sammlungen werden ungültig alle Iteratoren auf die Sammlung, so dass, wenn Sie erneut iterator nach einemresize
, die möglicherweise heap-Beschädigung, die manifestiertbad_alloc
Ausnahmen. Wenn Sie nicht aktiviert vector-element zugreift (std::vector::operator[]
), und die Indizes sind aus dem Bereich, dass kann die Ursache für heap-Beschädigung als gut.Der beste Weg, um track down heap-Beschädigung und-Speicher Fehler in der Regel ist die Verwendung eines heap-debugger wie valgrind
Klassen wie
std::vector
undstd::string
sind erlaubt zu werfenbad_alloc
oder andere Ausnahmen. Nachdem alle, Sie haben zu verwenden, einige Speicher, der kommt von irgendwo, und jeder computer hat nur so viel Speicher, um zu gehen.Standard 17.6.5.12/4:
Unklar. Wenn alle Variablen beziehen sich auf lokale, nicht. Wenn Sie mit malloc(), calloc () und free(), ja.
Nicht wenn man bad_alloc. Wenn du einen "stack overflow" Fehler, ja.
Gut, es ist schwer zu glauben, dass Sie eine lokale Kopie einer lookup-Tabelle in jedem stack-frame einer rekursiven Methode.
Natürlich. Sie können aus dem.
Heute unmöglich, ohne zu wissen, mehr über Ihre Daten-Strukturen.
Durch wen? Warum?
Erstellen Sie eine Instanz der Klasse auf dem stack. Ich denke. Bitte klären Sie.
Mit einer Zuordnung? Macht die Klasse einen Zuweisungsoperator? Ist es richtig? Hat die Klasse selbst verwenden heap-Speicher? Ist es richtig zugeordnet und gelöscht über Bau, Zerstörung und Aufgabe?
Da, wie Sie sagten, Sie sind mit
std::vector
mit default-Zuweisung, problem tritt auf, wenn Sie eine Menge vonstd::vector::resize(...)
und es tritt nach einigen Iterationen, meine Vermutung ist, dass Sie in der heap-Fragmentierung problem.