superponer - ¿El estándar C requiere que el tamaño de una matriz de n elementos sea n veces el tamaño de un elemento?
superponer graficas en r (2)
¿El estándar de C requiere que el tamaño de una matriz de n elementos sea n veces el tamaño de un elemento, ya sea por declaración explícita o por deducción lógica rigurosa de sus requisitos?
Por ejemplo, podría int (*x)[5] = malloc(5 * sizeof **x);
¿No puede solicitar espacio suficiente para una matriz de cinco int
?
C 2011 [N1570] 6.5.3.4 7 muestra un ejemplo de cálculo del número de elementos en una matriz como sizeof array / sizeof array[0]
. Sin embargo, los ejemplos no son una parte normativa de la norma (según el párrafo 8 del documento).
6.2.5 20 dice que un tipo de matriz describe un conjunto de objetos no vacíos asignados de forma contigua con un tipo particular, pero no dice nada sobre la memoria total requerida.
Esta es únicamente una pregunta de lenguaje-abogado; Las implementaciones reales son irrelevantes. (Para apaciguar a aquellos que desean ejemplos concretos, formule la hipótesis de una implementación de C que requiere administración de memoria adicional para arreglos grandes, por lo que crear una matriz requiere crear algunos datos adicionales para ayudar a administrar la memoria).
El único texto que describe la representación de arrays es bastante conciso, y está en lo que encontró en 6.2.5 ¶20:
Se puede construir cualquier número de tipos derivados a partir de los tipos de objeto y función, de la siguiente manera:
- Un tipo de matriz describe un conjunto de objetos no vacíos asignados de forma contigua con un tipo de objeto miembro particular, llamado tipo de elemento. El tipo de elemento se completará siempre que se especifique el tipo de matriz. Los tipos de matriz se caracterizan por su tipo de elemento y por el número de elementos en la matriz. Se dice que un tipo de matriz se deriva de su tipo de elemento, y si su tipo de elemento es T, el tipo de matriz a veces se llama '''' matriz de T ''''. La construcción de un tipo de matriz a partir de un tipo de elemento se denomina "derivación de tipo de matriz".
Tenga en cuenta que no dice algo como "conjunto de objetos y relleno no vacíos asignados de forma contigua", por lo que la matriz es solo los objetos. Por lo tanto, no parece haber ninguna base para una afirmación de que sizeof
the array [type] podría producir un resultado que no sea el tamaño del conjunto contiguo de objetos, que obviamente es N
veces el tamaño del tipo de elemento individual.
También vale la pena señalar que el relleno no es algo que solo puede existir por sí solo porque no se especifica que no exista. C especifica representaciones de tipos (6.2.6) y especifica explícitamente la posibilidad de rellenar bits y bytes cuando sea apropiado. No hay texto sobre el relleno para matrices, y por lo tanto no es parte de su representación.
Sí, se requiere que el tamaño de una matriz T[n]
sea n * sizeof (T)
.
La Norma define matrices en §6.2.5/20 :
Un tipo de matriz describe un conjunto de objetos no vacíos asignados de forma contigua con un tipo de objeto miembro particular ...
Además, el operador sizeof
produce el número total de bytes en la matriz ( §6.5.3.4/4 ):
Cuando se aplica sizeof ... a un operando que tiene un tipo de matriz, el resultado es el número total de bytes en la matriz. Cuando se aplica a un operando que tiene estructura o tipo de unión, el resultado es el número total de bytes en dicho objeto, incluido el relleno interno y posterior.
Dado que una matriz consiste en una asignación contigua de objetos, no puede haber un relleno interno. Y dado que el relleno posterior se menciona explícitamente con respecto al sizeof
operador solo en el contexto de uniones y estructuras, parece claro que se espera que los arreglos no posean dicho relleno posterior.
Finalmente, tenga en cuenta que en §6.2.6.1/4 se indica:
Los valores almacenados en objetos que no son de campo de bits de cualquier otro tipo de objeto constan de n x CHAR_BIT bits, donde n es el tamaño de un objeto de ese tipo, en bytes. El valor se puede copiar en un objeto de tipo unsigned char [ n ] (por ejemplo, por memcpy); El conjunto resultante de bytes se denomina representación del objeto del valor.
Suponiendo que las matrices puedan tener bytes de relleno posteriores, considere una matriz unsigned char A[n]
, y considere además la matriz unsigned char B[sizeof A]
, a la que se han incluido todos los bytes (incluidos los posibles bytes de relleno) de A[]
copiado Ahora, A[]
debe ser del mismo tamaño que B[]
, ya que ( §6.2.6.1/8 ):
Cuando se aplica un operador a un valor que tiene más de una representación de objeto, la representación de objeto que se use no afectará el valor del resultado.
Esto significaría que B[]
debe tener ningún relleno posterior, lo que significaría que los arreglos pueden tener bytes de relleno posteriores, excepto en ciertas condiciones especiales que no se mencionan en ninguna parte de la Norma, o que los conjuntos pueden tener relleno posterior, excepto los conjuntos de caracteres unsigned char
. Dado que ninguna de estas posibilidades se menciona en el Estándar, parece razonable concluir que los arreglos no deben tener un relleno posterior en primer lugar.