Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

331
Views
¿C o C++ garantizan matriz < matriz + TAMAÑO?

Supongamos que tiene una matriz:

 int array[SIZE];

o

 int *array = new(int[SIZE]);

¿C o C++ garantizan que array < array + SIZE , y si es así, dónde?

Entiendo que, independientemente de la especificación del idioma, muchos sistemas operativos garantizan esta propiedad al reservar la parte superior del espacio de direcciones virtuales para el kernel. Mi pregunta es si esto también está garantizado por el idioma , en lugar de solo por la gran mayoría de las implementaciones.

Como ejemplo, suponga que el kernel de un sistema operativo tiene poca memoria y, a veces, entrega la página más alta de memoria virtual a los procesos de usuario en respuesta a las solicitudes mmap de memoria anónima. Si malloc o ::operator new[] llama directamente a mmap para la asignación de una gran matriz, y el final de la matriz linda con la parte superior del espacio de direcciones virtuales de modo que la array + SIZE se ajusta a cero, ¿esto equivale a una cantidad no -cumplimiento de la aplicación de la lengua?

Aclaración

Tenga en cuenta que la pregunta no se refiere a array+(SIZE-1) , que es la dirección del último elemento de la matriz. Se garantiza que ese será mayor que array . La pregunta es sobre un puntero uno más allá del final de una matriz , o también p+1 cuando p es un puntero a un objeto que no es una matriz (que la sección del estándar apuntada por la respuesta seleccionada deja en claro que se trata de la misma manera ).

Stackoverflow me ha pedido que aclare por qué esta pregunta no es la misma que esta . La otra pregunta es cómo implementar la ordenación total de punteros. Esa otra pregunta esencialmente se reduce a cómo podría una biblioteca implementar std::less de modo que funcione incluso para punteros a objetos asignados de manera diferente, que el estándar dice que solo se pueden comparar por igualdad, no mayor y menor que.

Por el contrario, mi pregunta era si siempre se garantiza que uno más allá del final de una matriz sea mayor que la matriz. Si la respuesta a mi pregunta es sí o no, en realidad no cambia la forma en que implementaría std::less , por lo que la otra pregunta no parece relevante. Si es ilegal comparar con uno más allá del final de una matriz, entonces std::less simplemente podría exhibir un comportamiento indefinido en este caso. (Además, normalmente la biblioteca estándar es implementada por las mismas personas que el compilador, por lo que es libre de aprovechar las propiedades del compilador en particular).

over 4 years ago · Santiago Trujillo
6 answers
Answer question

0

C requiere esto. La Sección 6.5.8 párrafo 5 dice:

punteros a elementos de matriz con valores de subíndice más grandes comparar punteros mayores que a elementos de la misma matriz con valores de subíndice más bajos

Estoy seguro de que hay algo análogo en la especificación de C++.

Este requisito evita de manera efectiva la asignación de objetos que se envuelven alrededor del espacio de direcciones en el hardware común, porque no sería práctico implementar toda la contabilidad necesaria para implementar el operador relacional de manera eficiente.

over 4 years ago · Santiago Trujillo Report

0

Si. De la sección 6.5.8 párrafo 5 .

Si la expresión P apunta a un elemento de un objeto de matriz y la expresión Q apunta al último elemento del mismo objeto de matriz, la expresión de puntero Q+1 es mayor que P.

La array expresión es P. La array + SIZE - 1 apunta al último elemento de la array , que es Q. Por lo tanto:

array + SIZE = array + SIZE - 1 + 1 = Q + 1 > P = array

over 4 years ago · Santiago Trujillo Report

0

Se garantiza que la matriz tenga espacio de memoria consecutivo dentro. después de c++03, se garantiza que los vectores también tendrán uno para su &vec[0] ... &vec[vec.size() - 1] . Esto automáticamente significa que lo que estás preguntando es cierto.
se llama almacenamiento contiguo. se puede encontrar aquí para los vectores
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0944r0.html

Los elementos de un vector se almacenan de forma contigua, lo que significa que si v es un vector<T, Allocator> donde T es un tipo distinto de bool, entonces obedece a la identidad &v[n] == &v[0] + n para todo 0 <= n < v.tamaño(). Presuntamente, cinco años más de estudio de las interacciones de la contigüidad con el almacenamiento en caché dejaron en claro al WG21 que la contigüidad debía ser obligatoria y que la implementación de vectores no contiguos debería prohibirse claramente.

último es de documentos estándar. C++03 He acertado.

over 4 years ago · Santiago Trujillo Report

0

Esto se define en C++, desde 7.6.6.4 (p139 del borrador actual de C++23 ):

Cuando a una expresión P de tipo apuntador se le suma o resta una expresión J de tipo entero, el resultado es de tipo P.

(4.1) — Si P se evalúa como un valor de puntero nulo y J se evalúa como 0, el resultado es un valor de puntero nulo.

(4.2) — De lo contrario, si P apunta a un elemento de arreglo i de un objeto de arreglo x con n elementos (9.3.4.5) las expresiones P + J y J + P (donde J tiene el valor j) apuntan a (posiblemente- hipotético) elemento de matriz i + j de x si 0 <= i + j <= n y la expresión P - J apunta al (posiblemente hipotético) elemento de matriz i − j de x si 0 <= i − j <= n .

(4.3) — De lo contrario, el comportamiento no está definido.

Tenga en cuenta que 4.2 tiene explícitamente "<= n", no "< n". No está definido para ningún valor mayor que size(), pero está definido para size().

El orden de los elementos de la matriz se define en 7.6.9 (p141):

(4.1) Si dos punteros apuntan a diferentes elementos de la misma matriz, oa subobjetos del mismo, se requiere el puntero al elemento con el subíndice más alto para comparar mayor.

Lo que significa que el elemento hipotético n comparará más que la matriz en sí (elemento 0) para todos los casos bien definidos de n > 0.

over 4 years ago · Santiago Trujillo Report

0

La garantía no es válida para el caso int *array = new(int[SIZE]); cuando SIZE es cero.

Se requiere que el resultado de new int[0] sea un puntero válido al que se le puede agregar 0 , pero array == array + SIZE en este caso, y una prueba estrictamente menor que arrojará false .

over 4 years ago · Santiago Trujillo Report

0

La regla relevante en C++ es [expr.rel]/4.1 :

Si dos punteros apuntan a diferentes elementos de la misma matriz, oa subobjetos del mismo, se requiere el puntero al elemento con el subíndice más alto para comparar mayor.

La regla anterior parece cubrir solo los punteros a elementos de matriz, y array + SIZE no apunta a un elemento de matriz. Sin embargo, como se menciona en la nota al pie , un puntero pasado el final se trata aquí como si fuera un elemento de matriz. La regla de idioma relevante está en [basic.compound]/3 :

A efectos de la aritmética de punteros ([expr.add]) y la comparación ([expr.rel], [expr.eq]), un puntero más allá del final del último elemento de una matriz x de n elementos se considera equivalente a un puntero a un elemento de matriz hipotético n de x y un objeto de tipo T que no es un elemento de matriz se considera que pertenece a una matriz con un elemento de tipo T .

Entonces C++ garantiza que array + SIZE > array (al menos cuando SIZE > 0 ), y que &x + 1 > &x para cualquier objeto x .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!