Schnellste Möglichkeit, ein 2d-Array in C auf Null zu setzen?
Möchte ich wiederholt die null ein großes 2d-array in C. Dies ist, was ich im moment tun:
//Array of size n * m, where n may not equal m
for(j = 0; j < n; j++)
{
for(i = 0; i < m; i++)
{
array[i][j] = 0;
}
}
Ich habe versucht, mit memset:
memset(array, 0, sizeof(array))
Aber das funktioniert nur für 1D-arrays. Wenn ich printf () den Inhalt des 2D-Arrays, die erste Zeile ist null, aber dann bekam ich einen laden, der zufällig große zahlen und es stürzt ab.
InformationsquelleAutor der Frage Eddy | 2010-03-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wo
m
undn
sind die Breite und Höhe des zwei-dimensionalen Arrays (in deinem Beispiel, Sie haben einen quadratischen zwei-dimensionalen array, alsom == n
).InformationsquelleAutor der Antwort James McNellis
Wenn
array
ist wirklich ein array ist, dann können Sie "null out" mit:Aber es gibt zwei Punkte, die Sie wissen sollten:
array
ist wirklich ein "zwei-d-array", d.h. erklärt wurdeT array[M][N];
für irgendeine ArtT
.array
erklärt wurde. Wenn Sie übergeben es an eine Funktion, dann ist der namearray
zerfällt zu einem Zeigerundsizeof
wird nicht geben Sie die Größe des Arrays.Machen wir ein experiment:
Auf meine Maschine, die vor Drucke:
Obwohl
arr
ist ein array, es zerfällt zu einem Zeiger auf sein erstes element, wenn die übergebenef()
und daher die Größen gedruckt inf()
sind "falsch". Auch inf()
die Größe derarr[0]
ist die Größe des Arraysarr[0]
das ist ein "array [5] vonint
". Es ist nicht die Größe einesint *
ist, weil das "vergehen" geschieht nur auf der ersten Ebene, und das ist, warum wir brauchen, um zu erklärenf()
wie ein Zeiger auf ein array der richtigen Größe.So, wie ich schon sagte, was tun Sie waren ursprünglich nur funktionieren, wenn die beiden oben genannten Bedingungen erfüllt sind. Wenn nicht, werden Sie brauchen, um zu tun, was andere gesagt haben:
Schließlich
memset()
und diefor
Schleife, die Sie geschrieben sind nicht äquivalent im engeren Sinne. Könnte es werden (und wurden) Compiler, wo "alle bits null" nicht null ist, für bestimmte Arten, wie Zeiger und floating-point-Werte. Ich bezweifle, dass Sie sich sorgen machen müssen, dass, obwohl.InformationsquelleAutor der Antwort Alok Singhal
Gut, der Schnellste Weg, es zu tun ist nicht tun es überhaupt.
Klingt seltsam ich weiß, hier etwas pseudocode:
Eigentlich ist es ja noch den clearing-array, aber nur wenn etwas in das array geschrieben. Dies ist nicht ein großer Vorteil hier. Allerdings, wenn das 2D-array, implementiert unter Verwendung von, sagen wir, einen quad-tree (keine dynamische ein Geist), oder eine Sammlung von Zeilen von Daten, dann können Sie lokalisieren die Wirkung der boolean-flag, aber Sie brauchen mehr Fahnen. In der quad-tree setzen Sie einfach die leer-flag für die root-Knoten, in dem array von Zeilen setzen Sie einfach die fahne für jede Zeile.
Das führt zu der Frage "warum wollen Sie immer wieder null ein großes 2d-array"? Was ist die Matrix? Gibt es eine Möglichkeit, ändern Sie den code so, dass das array muss nicht genullt?
Zum Beispiel, wenn Sie hatte:
ist, verwenden Sie es für eine Akkumulation Puffer, dann ändern Sie es so verbessern würde die Leistung ohne Ende:
Dies erfordert nicht, dass das array gelöscht werden, aber immer noch funktioniert. Und das wird weit schneller, als löschen des array. Wie ich schon sagte, der Schnellste Weg ist, um es nicht tun in den ersten Platz.
InformationsquelleAutor der Antwort Skizz
Wenn Sie wirklich, wirklich besessen von Geschwindigkeit (und nicht so viel mit der Portabilität) ich denke, die absolute Schnellste Weg, dies zu tun wäre die Verwendung von SIMD-Vektor-Interna. z.B. auf Intel-CPUs, könnten Sie diese SSE2-Anweisungen:
Jeder store-Befehl wird festgelegt, vier 32-bit-ints auf null-eins-hit.
p muss 16-byte-ausgerichtet, aber diese Einschränkung ist auch gut für die Geschwindigkeit, weil wird es helfen, den cache. Die andere Einschränkung ist, dass p zeigen muss, um eine Zuordnung-Größe, die ein Vielfaches von 16 bytes, das ist aber auch cool, denn es ermöglicht uns zu entrollen Sie die Schleife einfach.
Haben dies in einer Schleife, und entrollen Sie die Schleife ein paar mal, und Sie haben eine verrückte schnelle initialiser:
Gibt es auch eine Variante von
_mm_storeu
umgeht den cache (d.h. Nullstellung der array nicht verschmutzen cache), die geben könnte Sie einige sekundäre Leistung nutzen in einigen Fällen.Finden Sie hier die für SSE2 Referenz: http://msdn.microsoft.com/en-us/library/kcwz153a(v=vs. 80).aspx
InformationsquelleAutor der Antwort Jarrod Smith
Wenn Sie Sie initialisieren das array mit
malloc
verwendencalloc
statt; Sie wird null, array kostenlos. (Gleiche perf offensichtlich, wie memset, nur mit weniger code für Sie.)InformationsquelleAutor der Antwort Ben Zotto
int array[N][M] = {0};
...zumindest im GCC 4.8.
InformationsquelleAutor der Antwort Arcane Engineer
Wie war dein 2D-array deklariert?
Wenn es so etwas wie:
Können Sie null, indem Sie Folgendes tun:
InformationsquelleAutor der Antwort Pablo Santa Cruz
Verwenden calloc statt malloc . calloc initiieren alle Felder auf 0.
int *a = (int *)calloc(n,size of(int)) ;
//alle Zellen wurden initialisiert auf 0
InformationsquelleAutor der Antwort DUDE_MXP
Ich denke, dass der Schnellste Weg, es zu tun mit der hand ist der folgende code. Vergleichen kann man es Geschwindigkeit zu memset-Funktion, aber es sollte nicht langsamer sein.
(Typ ändern von ptr und Zeiger ptr1, wenn Ihr array-Typ ist anders als int)
InformationsquelleAutor der Antwort mack369
InformationsquelleAutor der Antwort swestrup
Können Sie versuchen, diese
InformationsquelleAutor der Antwort Călin Calin
Dies geschieht, weil sizeof(array) gibt die Zuordnung der Größe des Objekts verweist array. (array ist nur ein Zeiger auf die erste Zeile der mehrdimensionalen array). Aber Sie zugeordnet j arrays der Größe ich. Folglich müssen Sie multiplizieren Sie die Größe einer Zeile, die zurückgegeben wird sizeof(array) wird mit der Anzahl der Zeilen, die Sie zugewiesen, z.B.:
Beachten Sie auch, dass sizeof(array) funktioniert nur für statisch zugewiesenen arrays. Für einen dynamisch zugewiesenen Arrays würde man schreiben
InformationsquelleAutor der Antwort VoidPointer