2016-05-31 8 views
-2

ich einige Array haben,memset auf float-Array nicht vollständig Null aus Array

float *large_float_array; 

, die ich calloc und Versuch nach einer Schleife

large_float_array = (float*)calloc(NUM, sizeof(float)); 

// .. do stuff with float array 

memset(large_float_array, 0, sizeof(large_float_array); 

// .. do other stuff 

memset aber es scheint large_float_array nicht wirklich Null ist 'd out. Warum ist das? Liegt das an den speziellen Eigenschaften von Fließkommazahlen? Wenn ja, frage ich mich, wie ich das beheben könnte.

P.S. funktioniert calloc tatsächlich auch hier?

+0

Ich habe gerade gefunden [https://mackiemathew.wordpress.com/2015/06/30/dont-use-memset-for-initializing-floats-or-doubles/], bietet einige Einblicke in meine Frage . –

+0

'memset (large_float_array, 0, sizeof (large_float_array);' kompiliert nicht. Immer freundlich um echten Code zu schreiben. – chux

+1

C schreibt nicht vor, dass Gleitkomma spezifisch ieee754 ist. Daher glaube ich, dass es keine Garantie in der Norm gibt '0.0f' ist bitweise-null – EOF

Antwort

3

Der Effekt der Initialisierung des Speicherbereichs von calloc und memset Funktion mit 0 Wert ist eigentlich das gleiche. Mit anderen Worten, calloc ist nicht mehr "typsicher" als memset. Beide setzen nur Speicher mit allen Bits Null *.

C11 (N1570) 7.22.3.2/2 Die calloc Funktion:

calloc Die Funktion ordnet Raum für eine Anordnung von Objekten nmemb, jeweils deren Größe eine Größe ist. Der Raum wird auf alle Bits Null initialisiert. 296)

Fußnote 296 (informativ only):

anzumerken, dass dies nicht die gleiche wie die Darstellung Gleitkommazahlen Null oder einen Nullzeiger konstant sein.


*) Es ist denkbar, dass calloc Adresse des Speicherplatzes zurückkehren konnte, die mit Nullen bereits vorinitialisiert ist, so kann es schneller sein, als malloc + memset Combo.

4

Sie können nicht memset verwenden, da es int als Werttyp akzeptiert, aber Schwimmer können auf unterschiedliche Art und Weise gespeichert werden, so dass Sie einen regelmäßigen Zyklus

size_t i 
for(i = 0; i < NUM; ++i){ 
    large_float_array[i] = 0.; 
} 
+0

Sie sollten verwenden 'size_t' anstelle von' int' für 'i', da' NUM' größer sein kann als 'int' – chqrlie

+0

@chqrlie hat C den Typ' size_t'? – LibertyPaul

+0

Ja, es ist definiert in '' (unter anderem) – chqrlie

1

Seit large_float_array ist ein Zeiger, können Sie nicht verwenden, verwenden sollten, sizeof(large_float_array), um die Anzahl der zu löschenden Bytes anzugeben. Sie müssen schreiben:

memset(large_float_array, 0, NUM * sizeof(float)); 

Beachten Sie, dass alle Bits Null gesetzt wird streng von der C-Standard nicht spezifiziert ist als alle Werte auf 0.0 Einstellung. Aber in den meisten aktuellen Architekturen wird es wie erwartet funktionieren.

Der richtige Weg, um Ihr Array zu löschen, ist dies:

#include <stdlib.h> 

... 
for (size_t i = 0; i < NUM; i++) { 
    large_float_array[i] = 0; 
} 
0

Beitrag über mehrere Probleme.

Folgendes ist nicht ausgeglichen (). Unklar, was der wahre Code von OP sein könnte.

memset(large_float_array, 0, sizeof(large_float_array); 

die obigen einfach weitere ) verwendet Angenommen, dann war Code nur ein paar Bytes Null Füllen mit Null als sizeof(large_float_array) ist die Größe eines Zeigers.

memset(large_float_array, 0, sizeof(large_float_array)); 

OP wahrscheinlich wollte etwas wie, die Null den zugewiesenen Raum mit Null Bits füllen würde. Dies bringt den zugewiesenen Speicher in den gleichen Zustand wie calloc().

memset(large_float_array, 0, NUM *sizeof *large_float_array); 

-Code sollte die folgende verwenden. Ein guter Compiler wird diese triviale Schleife in schnellen Code optimieren.

for (size_t i=0; i<NUM; i++) { 
    large_float_array[i] = 0.0f; 
} 

Ein Weg, um die schnelle memcpy() zu verwenden ist, um die float in das erste Element des Arrays zu kopieren, dann wird das erste Element mit dem zweiten Element, so werden die ersten 2 Elemente Elemente 3 & 4, dann werden die ersten 4 Elemente Elemente 4,5,6,7 ...

void *memset_size(void *dest, size_t n, const char *src, size_t element) { 
    if (n > 0 && element > 0) { 
    memcpy(dest, src, element); // Copy first element 
    n *= element; 
    while (n > element) { 
     size_t remaining = n - element; 
     size_t n_this_time = remaining > element ? element : remaining; 
     memcpy((char*)dest + element, dest, n_this_time); 
     element += n_this_time; 
    } 
    } 
    return dest; 
} 

float pi = M_PI; 
float a[10000]; 
memset_size(a, 10000, &pi, sizeof pi); 

wie bei allen Optimierungen zunächst klar geschriebenen Code betrachten und dann Kandidaten wie die in den ausgewählten Fällen oben verwenden, das es rechtfertigen.

Verwandte Themen