2016-04-26 5 views
2

Ich habe diese Codes:C++: Iterate mit Aufzählungstyp

for (i = 0; i <= WND_WRL; i++) { 
    syslog(LOG_ERR, "TESTE i=%d WND_WRL=%d", i,WND_WRL); 
} 

for (i = 0; i <= WND_WRL; i++) { 
    syslog(LOG_ERR, "OnScrDsp for i=%d WND_WRL=%d", i,WND_WRL); 
    m_pWnd[i] = gtk_window_new(GTK_WINDOW_POPUP); 
    assert(m_pWnd[i]); 
} 

Die erste für nur mein Problem zu erklären ist. Die zweite ist wirklich mein Problem. https://github.com/HuayraLinux/intel-classmate-function-keys/blob/master/OnScrDsp.cpp

Das Problem:

WND_WRL Variable von

typedef enum { 
    WND_BRG, 
    WND_DSP, 
    WND_WRL, 
} WND_ID; 

struct kam

Die Quelle des zweiten Codes kann hier gefunden werden.

Im ersten Code kann ich sehen, iterieren bis 2 (0,1,2) und WND_WRL wird immer 2. Das Problem ist in zweiten Code: sogar WND_WRL jemals 2 Wert drucken, das für iterieren i bis SIGV erhalten signal (11) und breche meine Bewerbung (hier höre ich mit i = 384 auf). Ich kann verstehen warum 384, ich mache mir darüber keine Sorgen.

Was ich nicht verstehe ist, warum die gleiche Bedingung verschiedene Möglichkeiten bieten. Wenn ich WND_WRL zu Nummer 2 ändere, bekomme ich korrekten Code und korrigiere die App-Ausführung.

Meine erste Idee ist der Block der Sekunde für vielleicht Änderung WND_WRL Wert, aber ist nicht passiert.

Ich kann verstehen, wenn dieser Code in falsche Speicherposition geschrieben wird, aber ich sehe immer WND_WRL mit 2 Wert.

LÖSUNG:

ändern Ausdruck "i < = WND_WRL" bis "i < WND_WRL", weil m_pWnd Größe. Es erklärt SIGV, aber nicht erklären, warum für weiter bis SIGV erhalten, auch wenn 2 < = 2 Bedingung übereinstimmt. Überschreibender Speicher, den wir kennen, kann eine Menge Dinge zerstören, aber Konstanten und Code sind schreibgeschützte Stapelspeicherbereiche, so dass m_pWnd [3] und andere i ++ nicht erklären können, warum das nicht aufhört.

+0

Wie wird 'm_pWnd' deklariert? Gehst du außerhalb der Grenzen des Arrays? – Thomas

+0

@FranciscoPanisKaseker diese Information zu der Frage hinzufügen, nicht in einem Kommentar. (S.: Wenn das Entfernen von Optimierungs-Flags Ihr Problem "behebt", klingt es so, als hätten Sie UB in Ihrem Code) – Borgleader

+0

@Thomas ja, weil ich SIGV (Signal 11) erhalten habe. Sie können die m_pWnd-Deklaration bei github sehen (besser als hier einfügen). –

Antwort

3

Variable m_pWnd wird im Quellcode als ein Array von Zeigern, mit einer Größe von 2, so gültiger Index 0 oder 1.

GtkWidget *m_pWnd[WND_WRL]; 

Aber Ihre Schleife geht i <= WND_WRL, definiert so i=2 Fall abstürzen

m_pWnd[i] = gtk_window_new(GTK_WINDOW_POPUP); 
+0

Ich stimme dir zu. Ich kann das ändern <= zu

+0

Wert von m_pWnd [2] ist unbekannt, _most wahrscheinlich_ zeigt auf m_pScr, vielleicht hat es sich woanders geändert, ich habe keinen Überblick über das ganze System, aber überschreiben Speicher ist wie Russian Roulette. WND_WRL ist immer 2, weil es eine Kompilierzeitkonstante ist, deren Wert nicht geändert werden kann. –

+0

Verstanden und ich stimme Russian Roulette. Aber etwas fehlt hier. Die Frage ist, warum ich weiter iteriere, wenn Bedingung übereinstimmt (2 <= 2). Da WND_WRL 2 ist und nicht zur Laufzeit geändert werden kann, können wir dasselbe für Code sagen. Wenn ich meinen Code im Stack-Speicher geschützt habe und ich dort nicht schreiben kann (schreibgeschützter Space), kann ich weiterhin Dinge tun (auch Condition Matches), bis ich SIGV vom Kernel bekomme. –