Ist der folgende korrekte Code?Verwenden eines zugewiesenen Speicherplatzes zum Speichern mehrerer Arrays
Angenommen, es ist bekannt, dass alle Objektzeigertypen gleiche Größe und Ausrichtung haben, mit einer Größe von nicht mehr als 8.
// allocate some space to A, and set *A and **A to different regions of that space
char*** A = malloc(92);
*A = (char**)((char*)A + 2*sizeof(char**));
**A = (char*)*A + 4*sizeof(char*);
// initialize the second char** object
A[1] = *A + 2;
// write four strings further out in the space
strcpy(A[0][0],"string-0-0");
A[0][1] = A[0][0] + strlen(A[0][0]) + 1;
strcpy(A[0][1],"string-0-1");
A[1][0] = A[0][1] + strlen(A[0][1]) + 1;
strcpy(A[1][0],"string-1-0");
A[1][1] = A[1][0] + strlen(A[1][0]) + 1;
strcpy(A[1][1],"string-1-1");
mir Sachen wie diese nützlich in Situationen, wo es nicht einfach sein kann wie ausplanen das Objekt. Angenommen, A [1] [1] kann der Adresse eines Zeichenfolgenliterals neu zugewiesen werden oder nicht. In beiden Fällen geben Sie einfach A frei. Außerdem wird die Anzahl der Aufrufe von malloc minimiert.
Mein Anliegen, dass dies möglicherweise nicht korrekt Code ist basiert auf dem folgenden. Mit einem Entwurf des Standards, die ich habe:
7.22.3 Speichermanagementfunktionen
- ... Der Zeiger zurückgegeben, wenn die Zuweisung geeigneter Weise ausgerichtet ist, gelingt es so, dass es eine zugeordnet werden kann Zeiger auf jede Art des Gegenstandes mit einer Grundvoraussetzung Ausrichtung und verwendet dann ein solches Objekt zuzugreifen oder eine Anordnung von solchen Objekten in dem Raum zugeordnet (bis der Raum explizit freigegeben wird), ...
So I bin garantiert, dass Sie den Platz als Array eines einzelnen Typs verwenden können. Ich kann keine Garantie finden, dass ich es als ein Array von zwei verschiedenen Typen (char * und char **) verwenden kann. Beachten Sie, dass die Verwendung einiger Leerzeichen als char-Arrays einzigartig ist, da auf jedes Objekt als zeichenartiges Array zugegriffen werden kann.
Die Regeln für den effektiven Typ stimmen mit diesem Ansatz überein, da niemals ein einzelnes Byte als Teil zweier verschiedener Typen verwendet wird.
Während die oben gibt es scheint keine explizite Verletzung der Norm zu sein, wird der Standard nicht explizit das Verhalten entweder erlauben, und wir haben Absatz 2 Kapitel 4 (Hervorhebung hinzugefügt):
Wenn ein Wird eine Anforderung außerhalb einer Integritätsbedingung oder Laufzeitbedingung verletzt, ist das Verhalten nicht definiert. Undefiniertes Verhalten wird in dieser Internationalen Norm durch die Wörter "undefined behaviour" oder durch Weglassen einer expliziten Definition des Verhaltens angegeben. Es gibt keinen Unterschied in der Betonung zwischen diesen drei; Sie alle beschreiben "Verhalten, das nicht definiert ist".
Das ist ein wenig vage, wenn das Speichermodell selbst so vage ist. Die Verwendung von Speicherplatz, der von malloc() zurückgegeben wird, um ein Array eines beliebigen Typs zu speichern, benötigt offensichtlich eine explizite Erlaubnis, die ich oben zitiert habe. Man könnte also argumentieren, dass die Verwendung dieses Raumes für disjunkte Arrays unterschiedlicher Typen ebenfalls eine explizite Berücksichtigung erfordert und ohne dieses als undefiniertes Verhalten gemäß Kapitel 4 zurückbleibt.
Also, um genau zu sein, wenn das Codebeispiel korrekt ist Was stimmt nicht mit dem Argument, dass es nicht explizit definiert und daher undefiniert ist, je nachdem, welcher Teil von Kapitel 4 aus dem oben zitierten Standard stammt?
'char *** A = malloc (90);' ist falsch mit einer Zeigergröße von 8 – 4386427
@ 4386427, danke, ich war ein wenig voreilig auf meine Arithmetik. – Kyle
@ 4386427, bekomme ich 6 Zeiger der Größe 8 haben die Größe 6 * 8 = 48 und 4 Stränge der Länge 10 machen 44, 48 + 44 = 92. – Kyle