2010-10-20 9 views
27

Ich versuche zu verstehen, was das bedeutet, ich den Code suchen bin an hatWas bedeutet "typedef void (* Etwas)()" bedeuten

in .h

typedef void (*MCB)(); 
static MCB  m_process; 

in .C

MCB Modes::m_process = NULL; 

Und manchmal, wenn ich

m_process(); 

ich tun Fehler bei Segmentierung erhalten, wahrscheinlich weil der Speicher freigegeben wurde. Wie kann ich debuggen, wenn er freigegeben wird?

Ich hoffe meine Fragen sind klar.

+9

Hey - reden Sie C oder C++ ? Ihre .C-Datei zeigt C++ an; Ihre Tags zeigen C. Entscheiden Sie sich - hier gibt es einen großen Unterschied zwischen den beiden Sprachen. –

+6

Das ist definitiv C++. '.C' ist eine gebräuchliche C++ Dateierweiterung, und außerdem wäre' Modes :: m_process' ungültig C. – SingleNegationElimination

+0

Der Autor hat das Tag eindeutig angegeben, er hat nach C gefragt, und er hat es mehrfach auf C bearbeitet. Ob er anfänglich einige Code mit anderen verwechselt, ist eine andere Diskussion. Die Antwort ist richtig und beantwortet ein C-Snippet. – another

Antwort

37

Es definiert einen Zeiger-zu-Funktionstyp. Die Funktionen geben void zurück, und die Argumentliste ist nicht spezifiziert, weil die Frage (momentan, möglicherweise aber fälschlicherweise) mit C markiert ist; Wenn es mit C++ markiert wäre, würde die Funktion überhaupt keine Argumente annehmen. Um eine Funktion zu machen, die keine Argumente (in C) nimmt, dann würden Sie verwenden:

typedef void (*MCB)(void); 

Dies ist einer der Bereiche, in denen es einen signifikanten Unterschied zwischen C ist, die nicht - noch - verlangen, dass alle Funktionen vor der Definition oder Verwendung prototypisiert werden, und C++, was tut.

+1

Ich würde für den Code stimmen, der als C++ kompiliert wird, aufgrund der zweiten Zeile in der ursprünglichen Frage, die den Bereichsauflösungsoperator verwendet. Trotzdem +1, um technisch korrekt zu sein. –

+1

Ich habe meins gelöscht, da es in der Tat mit C markiert ist. Ich habe mir den Code angesehen, obwohl ich C++ dachte. Dein deckt beide sowieso ab, also +1 dazu. – GManNickG

+1

@GMan: Ich verstehe die Verwirrung! –

3

Es führt einen Funktionszeigertyp ein, der auf eine Funktion verweist, die nichts zurückgibt (void), keine Parameter verwendet und den neuen Typ MCB nennt.

+1

Nein - es dauert nicht spezifizierte Parameter (weil die Frage C markiert ist), nicht Null-Parameter (wie es wäre, wenn es C++ markiert wäre). –

+0

Ja, und nein. Sehen Sie sich meinen Kommentar zu Ihrer Antwort an, warum ich denke, auf diese spezifische Art und Weise zu antworten (und wahrscheinlich die Frage neu zu markieren). –

+0

Ich verstehe und stimme zu/sympathisiere - Ich habe meine Antwort bearbeitet, um das wahrscheinliche Retagging zu ermöglichen und darauf hinzuweisen, dass es diesmal * wirklich * wichtig ist, ob die Frage C oder C++ ist. –

4

Der typedef definiert MCB als den Typ eines Zeigers auf eine Funktion, die keine Argumente akzeptiert und void zurückgibt.

Beachten Sie, dass MCB Modes::m_process = NULL; C++ ist, nicht C. Auch in C sollte der Typdef wirklich typedef void (*MCB)(void); sein.

Ich bin mir nicht sicher, was Sie mit "die Erinnerung wurde befreit" gemeint. Sie haben einen statischen Zeiger auf eine Funktion. Eine Funktion kann nicht freigegeben werden. Ihr Zeiger wurde höchstens irgendwo zurückgesetzt. Debuggen Sie einfach mit einer Speicherüberwachung auf m_process.

3

Es ist ein Funktionszeiger. Sie erhalten einen SEGMENTATION FAULT, weil Sie versuchen, eine Funktion aufzurufen, deren Adresse ungültig ist (NULL).

Entsprechend Ihrem spezifischen Beispiel sollte die Funktion keinen Wert (void) zurückgeben und sollte keine Parameter () erhalten.

Dies sollte funktionieren:

void a() 
{ 
    printf("Hello!"); 
} 

int main(int arcg, char** argv) 
{ 
    m_process = a; 
    m_process(); /* indirect call to "a" function, */ 
    // Hello! 
} 

Funktionszeiger für irgendeine Form von Veranstaltung in C. Umgang mit häufig verwenden Es ist nicht sein einziger obwohl Gebrauch ...