2010-12-28 6 views
11

Ich verstehe den Grund für einen Segmentierungsfehlerfehler in meinem Programm nicht. Der Code ist verfügbar hereDeklaration der Variablen verursacht Segmentierungsfehler

In Zeile 29 deklariere ich eine PclImage Variable, definiert mit typedef wie ein Array von struct. Die Definition von PclImage Typ ist die folgende (von src/libMyKinect.h-Datei):

typedef struct { 
    int valid; 
    float x; 
    float y; 
    float z; 
    unsigned char blue; 
    unsigned char green; 
    unsigned char red; 
} Point3d; 

typedef Point3d PclImage[480][640]; 

Das Programm funktioniert gut, aber wenn ich eine zweite PclImage erklären, ich so schnell einen Segmentation Fault, wie ich starten Sie das Programm.

Zum Beispiel, wenn in Zeile 30 der ersten Datei ich PclImage bgPcl; hinzufügen, stürzt das Programm sofort ab.

Kann mir jemand helfen?

Antwort

14

Wenn Sie eine PclImage als lokale Variable (auf dem Stapel) deklarieren, erhalten Sie wahrscheinlich einen Segmentierungsfehler aufgrund eines Stapelüberlaufs.

PclImage ist ein Array mit 307,200 Elementen, von denen jedes (wahrscheinlich) etwa 20 Byte groß ist, also ist das ganze Array etwa 6MB groß. Es ist sehr unwahrscheinlich, dass der Stack groß genug ist, um zwei dieser Arrays zu enthalten. Es ist möglicherweise nicht einmal groß genug, um einen zu enthalten (als allgemeine Regel ist es normalerweise auf den meisten Desktop-Betriebssystemen sicher, dass mindestens 1 MB Stapelspeicher verfügbar ist).

Wenn Sie solch große Objekte haben, sollten Sie sie dynamisch zuweisen (mit malloc und Freunden) oder, wenn Sie nicht mit Reentrancy beschäftigt sind, statisch.

1

Ich stimme James zu, dass die Zuordnung dieser großen Arrays auf dem Stapel höchstwahrscheinlich die Ursache ist. Jedoch addiert sich jedes nur zu ungefähr 6Meg jedes. Sofern Sie nicht in einer Umgebung mit begrenztem Speicher arbeiten, sollte dies machbar sein. Ich habe vorher viel größere Arrays auf dem Stack zugewiesen. Sogar auf eingebetteten Systemen.

James 'Vorschlag der Verwendung malloc wird wahrscheinlich es beheben (einen Versuch wert, nur um das Problem zu überprüfen). Ich halte es jedoch für eine gute Strategie, wenn möglich eine dynamische Zuordnung zu vermeiden. Eine mögliche Alternative zu malloc wäre, die Arrays im externen Kontext zu deklarieren oder die Stack-Größe des Threads zu erhöhen. Von Benutzern erstellte Prozesse und/oder Threads haben häufig ziemlich kleine Stapel, die ihnen standardmäßig zugewiesen sind. Es kann eine ziemlich einfache Angelegenheit sein, zu finden, wo das gesetzt ist, und es einen großen genug Stapel für Ihre Bedürfnisse geben.

Wenn dies beispielsweise von einem Thread ausgeführt wird, der mit der Windows-Routine CreateThread() erstellt wurde, steuert der zweite Parameter die Stapelgröße. Wenn Sie es standardmäßig mit einem 0 (wie die meisten Leute tun), nimmt es die Standard-Stack-Größe. Soweit ich das beurteilen kann, ist das "nur" 1 MB.

+0

Sie überschätzen drastisch den Speicher in einem eingebetteten System. Mit mehr als 32K RAM ist riesig. . . und ich nehme aus der Perspektive von 2017. Im Jahr 2010 fühlte 16K war die Verfügbarkeit in Teilen, wo wir für RAM pramged. – iheanyi

+0

@iheanyi - Wie in den Kommentaren gesagt, sind einige Geräte Speicher begrenzt, aber ich habe hier von Erfahrungen gesprochen, nicht Spekulationen. Natürlich, ymmv, aber das heißt nicht, dass jeder Embedded-Entwickler an einem System wie dem, an dem Sie arbeiten, arbeitet. –

Verwandte Themen