c++ c arrays pointers language-lawyer

c++ - Desreferenciando un 50% de puntero enlazado(matriz de matriz)



arrays pointers (3)

Lo que realmente quiero entender es lo que significa "p apunta al objeto x".

El objeto p contiene un valor que corresponde a la ubicación del objeto x en la memoria.

Eso es. Eso es todo lo que significa. Pareces decidido a hacer esto más complicado de lo necesario.

Los tipos de puntero no son tipos aritméticos, y no están destinados a ser arbitrariamente mancillados así. Los valores de puntero válidos se obtienen utilizando el operador unario & en un valor l, utilizando una expresión de matriz que no es el operando del operador sizeof o unary & , o llamando a una función de biblioteca que devuelve un valor de puntero.

Todo lo demás (tamaño, representación, físico frente a virtual, etc.) es un detalle de implementación , y las implementaciones varían ampliamente cuando se trata de representar direcciones. Es por eso que los estándares no dicen nada sobre qué esperar cuando juegas al Dr. Frankenstein con valores de puntero.

Si está íntimamente familiarizado con las convenciones de direccionamiento de su plataforma (tanto virtuales como físicas), y sabe cómo su implementación establece elementos en la memoria y cómo representa los tipos de puntero, y tiene un caso de uso válido para piratear sus valores de puntero de esta manera, luego navegue hasta el contenido de su corazón; ninguno de los estándares de lenguaje tiene nada que decir sobre el tema.

Esta es una nueva pregunta en mi colección "No entiendo los punteros en C y C ++".

Si mezclo los bits de dos punteros con valores iguales (apuntando a la misma dirección de memoria), que tienen exactamente la misma representación de bit, cuando uno es eliminable y uno pasa el final, ¿qué dice el estándar?

#include <stdio.h> #include <string.h> #include <assert.h> // required: a == b // returns a copy of both a and b into dest // (half of the bytes of either pointers) int *copy2to1 (int *a, int *b) { // check input: // not only the pointers must be equal assert (a == b); // also the representation must match exactly int *dest; size_t s = sizeof(dest); assert(memcmp(&a, &b, s) == 0); // copy a and b into dest: // on "exotic" architectures, size does''t have to be dividable by 2 size_t half = s/2; // = floor(s/2), char *pa = (char*)&a, *pb = (char*)&b, *pd = (char*)&dest; // copy half of a into dest: memcpy (pd, pa, half); // copy half of b into dest: memcpy (pd+half, pb+half, s-half); // s-half = ceil(s/2) //printf ("a:%p b:%p dest:%p /n", a, b, dest); // check result assert(memcmp(&dest, &a, s) == 0); assert(memcmp(&dest, &b, s) == 0); return dest; } #define S 1 // size of inner array int main(void) { int a[2][S] = {{1},{2}}; int *past = a[0] + S, // one past the end of inner array a[0] *val = &a[1][0], // valid dereferenceable pointer *mix = copy2to1 (past, val); #define PRINT(x) printf ("%s=%p, *%s=%d/n",#x,x,#x,*x) PRINT(past); PRINT(mix); PRINT(val); return 0; }

Lo que realmente quiero entender es: ¿qué significa "p puntos para objetar x"?

VER TAMBIÉN

Esta pregunta es una mejor versión de mis preguntas anteriores sobre una matriz de matrices:

  • ¿Es la memcpy de un puntero lo mismo que la asignación? que es una variación de mi otra pregunta:
  • Desreferenciando un puntero fuera de límite que contiene la dirección de un objeto (matriz de matriz)

y otras preguntas relacionadas sobre la validez del puntero:

  • ¿Las variables de puntero son números enteros con algunos operadores o son "místicas"?
  • y la pregunta de C ++: sobrescribir un objeto con un objeto del mismo tipo

La segunda afirmación

assert(memcmp(&a, &b, s) == 0);

puede fallar legítimamente, ya que los punteros que se comparan iguales no están obligados a tener una representación idéntica.

Una vez que se aprueba esta memcpy , todo lo demás está bien, porque memcpy es una forma legítima de copiar punteros. En el moderno C ++ - speak, los punteros son triviales y se pueden copiar. Está permitido ensamblar dichos objetos desde bytes y no importa de dónde provienen estos bytes.

Si dos de estos objetos son igual de memcmp , tienen el mismo valor (que es más fuerte que "comparar igual": son intercambiables, mientras que los punteros que se comparan no necesitan ser iguales). Al menos tal es el espíritu de la norma, no responderé por la carta.


En [basic.compound]:

Si un objeto de tipo T está ubicado en una dirección A , se dice que un puntero de tipo cv T* cuyo valor es la dirección A apunta a ese objeto, independientemente de cómo se obtuvo el valor .

past y val tienen la misma dirección, por lo que apuntan al mismo objeto. No importa que uno sea "uno más allá del final" de la primera fila y el segundo es el primer elemento de la segunda fila. Hay un objeto válido en esa dirección, por lo que todo aquí es perfectamente razonable.

En C ++ 17, a partir de P0137 , esto cambia mucho. Ahora, [basic.compound] define punteros como:

Cada valor del tipo de puntero es uno de los siguientes:
- un puntero a un objeto o función (se dice que el puntero apunta al objeto o función), o
- un puntero más allá del final de un objeto (5.7), o
- el valor del puntero nulo (4.11) para ese tipo, o
- un valor de puntero no válido .

Entonces, past es un valor del segundo tipo (un puntero pasado el final de), pero val es un valor del primer tipo (un puntero a). Esas son diferentes categorías de valores y no son comparables:

Un valor de un tipo de puntero que sea un puntero o pase del final de un objeto representa la dirección del primer byte en la memoria (1.7) ocupada por el objeto o el primer byte en la memoria después del final del almacenamiento ocupado por el objeto , respectivamente. [Nota: No se considera que un puntero más allá del final de un objeto (5.7) apunte a un objeto no relacionado del tipo del objeto que podría estar ubicado en esa dirección. Un valor de puntero pierde validez cuando el almacenamiento que denota alcanza el final de su duración de almacenamiento; ver 3.7. -finalizar nota]

past no apunta a algo, por lo que ver su contenido como si fuera lo mismo que val ya no es significativo.