2010-12-31 7 views
1

Beispielcode:Überprüfen Sie, ob das 2D-Pointer-Array einen benutzerdefinierten Wert in C hat?

float** a; 
a = (float**) malloc(numNodes * sizeof(float*)); 
for(int i=0; i<`numNodes`; i++) 
{ 
    a[i] = (float*)malloc((numNodes-1) * sizeof(float)); 
} 

Ich bin ein dynamischen 2D-Array zu schaffen oben. Vor dem Auffüllen bemerkte ich, dass jeder Block im Array bereits diesen Wert enthält: -431602080.000000 und nicht NULL. Warum ist das?
Es gibt Situationen, in denen nicht alle Bereiche innerhalb des Arrays verwendet werden.
Also, meine Abfrage ist einfach, Gibt es eine elegante Möglichkeit zu überprüfen, ob der jeweilige Block diesen Standardwert oder einen benutzerdefinierten Wert hat?

Vielen Dank im Voraus.

Antwort

0

In C werden automatische Variablen nicht automatisch initialisiert. Sie müssen Ihre Variable explizit auf 0 setzen, wenn es das ist, was Sie wollen.

Dasselbe gilt für malloc, das den Speicherplatz auf dem Heap, den es zuweist, nicht initialisiert. Sie können calloc verwenden, wenn Sie es initialisieren möchten:

a = malloc(numNodes*sizeof(float*)); // no need to initialize this 
for ... { 
    a[i] = calloc(numNodes-1, sizeof(float)); 
} 
+0

Peoro: wenn es es nicht initialisiert dann was ist das -431602080.000000? dass jeder Block zu haben scheint? – Freddy

+0

Wenn Sie im Debug-Modus ausgeführt werden, sollte dies ein magischer Wert sein, der Ihnen zeigt, dass Sie nicht initialisierte Daten verwenden. –

+0

Es könnte was auch immer sein. Es könnte der Wert sein, den ein Teil des Speichers vor Ihrem Anruf enthielt. – peoro

1

C Runtimes sind keine Speicher initialisieren erforderlich, dass Sie sich nicht initialisiert haben und die Werte, die sie halten, sind im Wesentlichen zufällig Müll aus der letzten Zeit übrig dieser Speicher wurde benutzt. Sie müssen alle zuerst explizit auf NULL setzen oder Calloc verwenden.

0

Vor dem Auffüllen bemerkte ich, dass jeder Block im Array bereits diesen Wert enthält: -431602080.000000 und nicht NULL. Warum ist das?

initialisiert nicht den Speicher, den es zuweist. Sie müssen calloc() verwenden, wenn Sie 0 Initialisierung wollen

Die calloc() Funktion ordnet ungenutzten Raum für eine Reihe von nelem Elemente enthält, deren jeweilige Größe in Bytes ist elsize. Der Raum ist auf alle Bits 0

+0

Danke Prasoon. Ich sehe, dass ich von nun an immer Calloc benutzen muss, wenn ich malloc benutze. – Freddy

2

Der Inhalt des Speichers mit malloc (sowie der Variablen auf dem Stack zugeordnet) zugeordnet initialisiert ist undefined, so dass es sehr gut alles sein kann. Normalerweise erhalten Sie Speicherplatz, der mit Nullen gefüllt ist (weil das Betriebssystem Speicherseiten blättert, die von anderen Prozessen verwendet wurden) oder Reste der vorherigen Verwendung dieser Speicherseiten (dies ist häufig der Fall, wenn die Speicherseite zu Ihrem Prozess gehört), aber dies ist was unter der Haube passiert, der C-Standard gibt keine Garantien.

Also, im Allgemeinen gibt es keinen "Standardwert" und keine Möglichkeit zu überprüfen, ob Ihr Speicher geändert wurde; Sie können jedoch die Speicherblöcke initialisieren, die Sie mit magischen Werten verwenden, von denen Sie sicher sind, dass sie nicht als "echte Daten" verwendet werden, aber es handelt sich lediglich um eine interne Konvention für Ihre Anwendung.

Glücklicherweise gibt es für Gleitkommavariablen mehrere magische Werte wie leises NaN, das Sie für diesen Zweck verwenden können; Im Allgemeinen können Sie das in <math.h> definierte Makro NAN verwenden, um float auf NaN zu setzen.

By the way, sollten Sie nicht uninitialized lesen float s und double s, da das übliche Format sie in (IEEE 754) enthält einige magische Werte gespeichert werden (wie die Signal-NAN), die arithmetische Ausnahmen auslösen können, wenn sie Lesen Sie, wenn Ihr nicht initialisierter Speicher also ein solches Bitmuster enthält, wird Ihre Anwendung wahrscheinlich abstürzen.

+0

+1, ein Zweifel: Sie sagten 'os Leerzeichen Speicherseiten von anderen proc verwendet' ist es so? Ich meine, warum os sich darum kümmern sollte, einen langen Speicherbereich auf Null zu setzen. Gibt es dafür einen (offensichtlichen) Grund? –

+0

@ Vikram.exe: Stellen Sie sich vor, Sie haben eine Anwendung, die Kreditkartennummern verarbeitet; Wären Sie glücklich, wenn Ihre freigegebenen Speicherseiten für vollständig unabhängige Prozesse unangetastet bleiben würden? –

+0

Nein, ich würde nicht, also werde ich explizit den Speicherinhalt selbst löschen (aus meinem Programm). Das zugrundeliegende Betriebssystem würde nicht. Recht?Dies ist ein zusätzlicher Aufwand für das Betriebssystem, um solche (wahrscheinlich unnötigen) Operationen durchzuführen. –

1

die gute Antwort von Matteo Italia Erweiterung:

Der Code der Initialisierung eines einzelnen Array würde wie folgt aussehen:

float* row; 

row = malloc(numNodes*sizeof(float)); 
for (int i=0; i<numNodes; ++i) { 
    row[i] = nanf(); // set a Not-a-Number magic value of type float 
} 

(ich werde es Ihnen überlassen, um dies zu ändern, um Ihre mehrdimensionales Array)

Dann irgendwo:

float value = ...; // read the array 
if (isnan(value)) { 
    // not initialized 
} else { 
    // initialized - do something with this 
} 

Eine Sache ist wichtig zu erinnern: NaN == NaN wird false, so ist es am besten isnan(), nicht == zu verwenden, um auf das Vorhandensein dieses Werts zu testen.

+0

Oho, es macht immer viel Spaß mit den magischen fp Werten umzugehen :) –