[solved] VS2015 - fatal error C1060: Kein verfügbarer Speicher mehr im Heap
-
Hi,
bin nicht sicher, ob es hier richtig ist. Aber für ein Tool benötigen wir einen zusammenhängenden Datenblock, der in die Anwendung einkompiliert werden soll. Eingebunden wird dieser mittels einer Header Datei (hier als kurzes ausführbares Beispiel):
data.h:
#pragma once //#include <array> //#include <vector> unsigned char data [] = { 0, 1, 2 }; //unsigned char *data = new unsigned char [3] { 0, 1, 2 }; //std::array <unsigned char, 3> data = { 0, 1, 2 }; //std::vector <unsigned char> data = { 0, 1, 2 };
main.cpp
#include "data.h" int main () { unsigned char *test = data; //unsigned char *test = data.data (); // Zugriff auf Array/Vector //delete [] data; return 0; }
Dabei kann die Größe der "data" Datei mitunter locker 50MB (d.h. min. 10 Mio Elemente) übersteigen (weshalb sich auch das Visual Studio schon beim versehentlichen Öffnen aufhängt
).
Das eigentliche Problem: der Visual Studio 2015 Compiler verabschiedet sich mit "fatal error C1060: Kein verfügbarer Speicher mehr im Heap". Der Intel Compiler 16 hingegen kompiliert das anstandslos und die Anwendung lässt sich einwandfrei ausführen/debuggen. Auch das Umstellen auf ein std::array oder std::vector bringt keine Verbesserung.
2 Fragen: Wo liegt hier das Problem? Arbeitsspeicher ist mehr als genug vorhanden und wenigstens new/array/vector sollten diesen doch auch nutzen!? Ist das evtl. ein bekannter Bug der Initialisierung im VS Compiler?
Und gibt es eine Möglichkeit unser Vorhaben besser zu realisieren? Die Anwendung soll beim Nutzer keine zusätzlichen Dateien einlesen und die Daten sollen auch nicht mittels Resource-Viewer sichtbar werden.Besten Dank
-
Hilft evtl. /HEAP (Heapgröße festlegen)?
-
Redest du jetzt davon, dass der Compiler selbst abstürzt, oder das vom Compiler erstellte Programm?
PS: Warum große Daten in eine Anwendung eincompilieren? Klingt mehr als fragwürdig. Beschreib mal, wieso du das für eine gute Idee hältst, dann sagen wir dir, wie man es wirklich macht. Das löst dann auch indirekt dein anders Problem.
-
Wahrscheinlich generiert Ihr den Code doch selbst, richtig? Dann versucht doch, einfach eine Binär-Datei daraus zu machen und dann direkt in die Applikation zu _linken_. Das sollte auch mit dem MSVC möglich sein.
Wollt Ihr die Daten wirklich ändern? Wenn nicht, dann als Konstante deklarieren, dass sollte den Speicherbedarf halbieren.
mfg Torsten
-
Th69 schrieb:
Hilft evtl. /HEAP (Heapgröße festlegen)?
Danke dir. Habe jetzt sowohl die Heap, als auch einfach mal die Stack-Size auf 100MB hochgeschraubt, aber er bricht das Kompilieren leider dennoch ab. Obwohl die Daten beim Testen nur knapp 5MB groß waren.
SeppJ schrieb:
Redest du jetzt davon, dass der Compiler selbst abstürzt, oder das vom Compiler erstellte Programm?
PS: Warum große Daten in eine Anwendung eincompilieren? Klingt mehr als fragwürdig. Beschreib mal, wieso du das für eine gute Idee hältst, dann sagen wir dir, wie man es wirklich macht. Das löst dann auch indirekt dein anders Problem.
Der VS2015 Compiler bricht schon das Kompilieren ab, mit dem genannten Fehler. Und da der Intel Compiler das aber macht, kam die Frage auf.
Oh, das können z.B. Media-Objekte sein, die bereits aufbereitet und mittels Boost serialisiert wurden. Sie sollten in der Anwendung (welche auch eine DLL sein kann) einkompiliert sein, da wir sie 1) schnell benötigen und 2) das Problem haben, das z.B. ein Host dank strengem Sandboxing den Zugriff auf externe Daten unterbindet.
Torsten Robitzki schrieb:
Wahrscheinlich generiert Ihr den Code doch selbst, richtig? Dann versucht doch, einfach eine Binär-Datei daraus zu machen und dann direkt in die Applikation zu _linken_. Das sollte auch mit dem MSVC möglich sein.
Wollt Ihr die Daten wirklich ändern? Wenn nicht, dann als Konstante deklarieren, dass sollte den Speicherbedarf halbieren.
mfg Torsten
Wir haben ein Konsolen-Tool, welches die benötigten Daten aus diversen Ordnern aufbereitet und uns dann das Header ausspuckt. Das können wir einfach in die Hauptanwendung kopieren und mitkompilieren.
Die Möglichkeit des Linkens schau ich mir mal an, danke dir.
-
Hast du die Ratschläge auf der MSDN Seite bezüglich des Fehlers abgearbeitet? Insbesondere: hast du die 64 Bit Toolchain getestet?
In einem echten Programm erhältst du ein mehrfach definiertes Symbol, wenn du den Header in mehr als einer cpp-Datei benutzt. Die Daten gehören eher in eien eigene cpp-Datei.
-
manni66 schrieb:
Hast du die Ratschläge auf der MSDN Seite bezüglich des Fehlers abgearbeitet? Insbesondere: hast du die 64 Bit Toolchain getestet?
In einem echten Programm erhältst du ein mehrfach definiertes Symbol, wenn du den Header in mehr als einer cpp-Datei benutzt. Die Daten gehören eher in eien eigene cpp-Datei.
Ja, MSDN ist immer die erste Anlaufstelle. Die meisten Ratschläge dort helfen bei diesem Projekt leider gar nicht, da bereits das kleine Beispiel oben (wenn mehr Daten drin stehen würden) nicht funktioniert - und das ist nun wirklich aufs Minimalste gekürzt. Das 64-Bit Toolset ist aktiviert, hat aber auch nichts gebracht.
Habens auch nochmal mit älteren VS Versionen/Compilern probiert, nur die unterstützen teils die Init-Liste wieder nicht
Habe das Probjekt auch aus Verzweiflung mal auf andere Partitionen geschoben, um vielleicht irgendwelche internen Zugriffsfehler auszuschließen.
Ich werde jetzt nochmal schauen wie XCode mit diesem Test-Projekt umgeht.
-
manni66, du meinst folgenden Link: Fatal Error C1060?
Wenn es schon beim Kompilieren und nicht erst beim Linken auftritt, dann mal den Tipp mit der Option "/Zm" ausprobieren.
Und beachte auch den Tipp von manni66 bzgl. Daten in eigene CPP-Datei packen - evtl. vorher mal überprüfen, ob du bisher vordefinierte Header aktivierst hast...
-
Okay, das Problem scheint gelöst zu sein.
Es lag tatsächlich daran, dass das Array im Header und nicht in der cpp stand. Einfach in die cpp gepackt, noch eine get-Funktion geschrieben - das wars erstmal.
Danke an alle für die schnelle und gute Hilfe
-
Boolshit schrieb:
Das 64-Bit Toolset ist aktiviert, hat aber auch nichts gebracht.
Das Problem ist ja gelöst, aber ich bin mir nicht sicher, ob du das mit der 64 Bit richtig verstanden hat: gemeint waz nicht das erzeugte Programm, sondern der Compiler selbst. Der ist nämlich im Normalfall selber ein 32 Bit Programm. Man kann (AFAIK nur auf der Kommandozeile) aber auch eine 64 Bit Version des Compilers benutzen.
-
Hab mich falsch ausgedrückt. Ja genau, auf der MSDN Seite gibbet ja die Anleitung, dass man erst die Batch Datei aufruft usw.. Aber das hatte nicht geholfen.
Dass der Datenblock letztlich nur an den richten Platz geschoben werden musste, kam unerwartetBeim nächsten Fehler achtet man dann auch auf sowas.