2010-11-25 21 views
3

Ich stellte mir zufällig eine Frage über Arrays in C++. Nun, wir alle wissen, dass Arrays feste Sammlungen von etwas sind, sage ich behoben, weil es notwendig ist, Array-Länge bei der Definition von Arrays zu deklarieren. Nun, lassen Sie uns ein Beispiel betrachten:Umgang mit Array-Größe

char myarray[10] = {'\0'}; 
int sz = sizeof(myarray); // It is supposed to be 10 

Nun, es ist richtig, 10 die Zahl von sizeof zurückgegeben wird. Dies kann vom Compiler erledigt werden, da er weiß, wie viel Platz er für diese Variable einnimmt.

Betrachten wir nun, was in dieser Situation passiert:

void dosome(mystruct* arr) { 
    int elements = sizeof(arr)/sizeof(mystruct); 
    for (int i = 0; i < elements; i++) { 
     // Do something hoping no overflow will ever occur 
    } 
} 

Nizza ... aber ich nehme an, es Überlauf anfällig sein kann. Wenn ich auf diese Funktion ein Array übergebe ich in einer „normalen“ Art und Weise erstellt, soll alles in Ordnung sein:

mystruct array[20]; 
dosome(array); 

Kein Problem. Aber wenn ich dies tun:

mystruct* array = (mystruct*)malloc(80*sizeof(mystruct)); 
dosome(array); 

WAS PASSIERT ??????????????????? Ich möchte gerne verstehen, wie sich die Größe verhält, diese Funktion wird zur Kompilierzeit richtig ausgewertet ??? ok, was passiert wenn ich kein Array benutze, aber etwas sehr umständliches wie ein Datenblock wie dieser? außerdem könnte ich es mit einem weiteren Aufruf an malloc erneut zuweisen und Dosome bitten, diesen Datenblock erneut zu verarbeiten. Wird es funktionieren? Ich könnte es physisch versuchen, aber ich würde eine genaue Antwort über das Verhalten von sizeof bekommen.

Vielen Dank.

+2

In 'dosome',' sizeof (arr) 'ist' sizeof (mystruct *) 'unabhängig von der Art und Weise der Funktion – icecrime

+0

aufgerufen wird Wenn Sie in C++ entwickeln, Verwenden Sie dann 'new' anstelle von' malloc' wann immer möglich.Verhält sich Ihr Code immer noch falsch, wenn Sie Ihr Array wie folgt definieren: 'mystruct * array = new mystruct [20];'? – suszterpatt

+0

icecrime hat recht, du hast falsche Erwartungen – Simone

Antwort

1
void dosome(mystruct* arr) { 
    int elements = sizeof(arr)/sizeof(mystruct); 
    for (int i = 0; i < elements; i++) { 
     // Do something hoping no overflow will ever occur 
    } 
} 

Welchen Typ hat arr in diesem Beispiel? mystruct*! Und seine Größe ist höchstwahrscheinlich 4 oder 8. Wenn Sie statisch/automatisch zugewiesene Arrays (nicht neu) an Funktionen übergeben möchten, die die Größe erhalten, damit Ihr Trick funktioniert, gehen Sie nach REFERENCE über!

template <int N> 
void dosome(mystruct (& arr) [N]) { 
    for (int i = 0; i < N; i++) { 
     // Do something . No overflow will occur 
    } 
} 

Auch diese Notiz

int a[20]; 
sizof a; //equals to 20*sizeof(int) 
int* b = new int [20]; 
sizeof b; //equals to sizeof pointer, most likely 4 
+0

AHHH ok, das ist es, was ich wissen wollte ... also ist es anders, dass ein [20] und * b ... -Compiler die Größe dank [Nummer] erkennen kann !! Vielen Dank. – Andry

2

es ist falsch ab dem mystruct array[20] Beispiel. Da die Funktion einen Zeigertyp und keinen Array-Typ empfängt, kann die Anzahl der Elemente im Array nicht abgeleitet werden. Sie erhalten tatsächlich die Größe eines mystruct*, wenn Sie sizeof(arr) durchführen.

Sie können Vorlagen verwenden, um Funktionen zu schreiben, die Arrays als Parameter nehmen, aber der vorgeschlagene Weg in C++ ist vector s zu verwenden, wenn ich nicht falsch liege.

Der "Weg" Arrays zu erhalten als Parameter, wie etwas zu schreiben wäre:

template <int N> void somefunction(int (&v)[N]); 

EDIT die Funktionsdeklaration korrigiert. Hoppla.

+1

Der vorgeschlagene Weg, um diese Art von Sache zu einer Funktion in C++ zu übergeben, ist die Verwendung von Paaren von Iteratoren :-) Wenn das fehlschlägt (z. B. wollen Sie nicht jede Funktion, die Sie schreiben zu templated), a Vektor könnte tun, oder ein Zeiger und eine Länge. –

+1

'Vorlage void somefunction (int (& v) [N]);' – Anycorn

+0

-1: Ihre Funktionsdeklaration entspricht der folgenden: 'template void somefunction (int * v);' –

0

sizeof ist ein Kompilieroperator. Und hier berechnet es nur die Größe eines Zeigers.