virtuales traduccion retornar puntero proceso memoria lógica logicas logica física fisicas fisica espacio entre dirección direcciones direccion diferencia caracteristicas asignado c++ c computer-architecture memory-address

c++ - traduccion - ¿Qué espacios de direcciones de memoria hay?



retornar un puntero en c (2)

¿Qué formas de espacios de direcciones de memoria se han utilizado?

Hoy en día, un gran espacio de direcciones virtuales planas es común. Históricamente, se han utilizado espacios de direcciones más complicados, como un par de una dirección base y un desplazamiento, un par de un número de segmento y un desplazamiento, una dirección de palabra más algún índice para un byte u otro subobjeto, etc. .

De vez en cuando, varias respuestas y comentarios afirman que los punteros de C / C ++ son esencialmente enteros. Ese es un modelo incorrecto para C / C ++, ya que la variedad de espacios de direcciones es sin duda la causa de algunas de las reglas de C sobre las operaciones de puntero. Por ejemplo, no definir la aritmética de punteros más allá de una matriz simplifica la compatibilidad con los punteros en un modelo base y de compensación. Los límites en la conversión de punteros simplifican el soporte para los modelos de dirección más datos extra.

Esa afirmación recurrente motiva esta pregunta. Estoy buscando información sobre la variedad de espacios de direcciones para ilustrar que un puntero de C / C ++ no es necesariamente un número entero simple y que las restricciones de C / C ++ en las operaciones de punteros son razonables dada la gran variedad de máquinas que se admiten.

La información útil puede incluir:

  • Ejemplos de arquitecturas de computadora con varios espacios de direcciones y descripciones de esos espacios.
  • Ejemplos de varios espacios de direcciones todavía en uso en las máquinas que se fabrican actualmente.
  • Referencias a documentación o explicación, especialmente URLs.
  • Elaboración de cómo los espacios de direcciones motivan las reglas de puntero de C / C ++.

Esta es una pregunta amplia, por lo que estoy abierto a sugerencias sobre cómo manejarlo. Me encantaría ver la edición colaborativa en una sola respuesta generalmente inclusiva. Sin embargo, eso puede dejar de otorgar reputación como merecido. Sugiero votaciones múltiples contribuciones útiles.


Yo diría que está haciendo la pregunta equivocada, excepto por curiosidad histórica.

Incluso si su sistema usa un espacio de direcciones plano, de hecho, incluso si todos los sistemas desde ahora hasta el fin de los tiempos usan un espacio de direcciones plano, aún no puede tratar los punteros como enteros.

Los estándares C y C ++ dejan todo tipo de aritmética de punteros "indefinida". Eso puede impactarle ahora mismo, en cualquier sistema, porque los compiladores asumirán que usted evita el comportamiento indefinido y optimiza en consecuencia.

Para un ejemplo concreto, hace tres meses apareció un error muy interesante en Valgrind:

http://comments.gmane.org/gmane.comp.debugging.valgrind.devel/19698

(Buscar "comportamiento indefinido".)

Básicamente, Valgrind usaba menos que y más que los punteros para tratar de determinar si una variable automática estaba dentro de un cierto rango. Debido a que las comparaciones entre punteros en diferentes agregados son "indefinidas", Clang simplemente optimizó todas las comparaciones para devolver una constante verdadera (o falsa; lo olvido).

Este error en sí mismo generó una interesante pregunta de .

Entonces, si bien las definiciones aritméticas de los punteros originales pueden haberse dirigido a máquinas reales, y eso podría ser interesante por su propio bien, en realidad es irrelevante para la programación actual. Lo que es relevante hoy es que simplemente no puede asumir que los punteros se comportan como enteros, punto, independientemente del sistema que esté utilizando. "Comportamiento indefinido" no significa "sucede algo gracioso"; significa que el compilador puede asumir que no te involucras en él. Cuando lo haces, introduces una contradicción en el razonamiento del compilador; y de una contradicción, todo sigue ... Sólo depende de qué tan inteligente sea su compilador.

Y se vuelven más inteligentes todo el tiempo.


Casi cualquier cosa que puedas imaginar probablemente haya sido usada. La primera división importante es entre el direccionamiento de bytes (todas las arquitecturas modernas) y el direccionamiento de palabras (anterior a IBM 360 / PDP-11, pero creo que los mainframes modernos de Unisys todavía tienen direccionamiento de palabras). En el direccionamiento de palabras, char* y void* menudo serían más grandes que int* ; incluso si no fueran más grandes, el "selector de bytes" estaría en los bits de orden superior, que debían ser 0, o se ignoraría para cualquier otra cosa que no sean bytes. (En un PDP-10, por ejemplo, si p era un char* , (int)p < (int)(p+1) menudo sería falso, aunque int y char* tuvieran el mismo tamaño).

Entre las máquinas con direcciones de bytes, las principales variantes son las arquitecturas segmentadas y no segmentadas. Ambos todavía están muy extendidos en la actualidad, aunque en el caso de Intel de 32 bits (una arquitectura segmentada con direcciones de 48 bits), algunos de los sistemas operativos más utilizados (Windows y Linux) restringen artificialmente los procesos de los usuarios a un solo segmento, simulando un direccionamiento plano.

Aunque no tengo experiencia reciente, esperaría aún más variedad en los procesadores integrados. En particular, en el pasado, era frecuente que los procesadores incrustados usaran una arquitectura de Harvard, donde el código y los datos se encontraban en espacios de direcciones independientes (de modo que un puntero de función y un puntero de datos, convertidos en un tipo integral lo suficientemente grande, pudieran comparar ).