Dirección de memoria C++
memory (4)
La siguiente dirección 2 es 003EFAA8 (Aquí es donde me cuesta entender. Mi entendimiento es que la siguiente dirección debería ser 003EFAA5, considerando que el carácter es de 1 byte?
Cuando haces
&name + 1
, vas a la siguiente dirección del tipo de
name
.
Aunque el
name
no es un
char
.
Es un
char*
y en su sistema un
char*
tiene un tamaño de 4. Por eso avanza 4 bytes, ya que es donde se puede ubicar el próximo
char*
.
La siguiente dirección 2 es 003EFAB4 (Aquí es donde me cuesta entender también. Mi entendimiento es que la siguiente dirección debe ser 003EFAA8 cuando la dirección del nombre de la variable es 003EFAA4 considerando que el tamaño del puntero de caracteres es de 4 bytes.
Esto es básicamente lo mismo que está sucediendo arriba, pero en lugar de ir al siguiente
char*
, se va al elemento siguiente de
sizeof name
, que en este caso es el cuarto elemento.
Por favor, disculpe si esta es una pregunta repetida.
Este es mi codigo
#include "stdafx.h"
#include <stdio.h>
#include "iostream"
#include <stdlib.h>
using namespace std;
int main()
{
char * name = "Hello";
cout << "2" << endl;
cout << "Address2 is " << &name << " value at address is " << * (&name) << endl;
cout << "Next address2 is " << &name + 1 << " value at address is " << name + 1 << " " << sizeof(char) << endl;
cout << "3" << endl;
cout << "Address3 is " << &name << " value at address is " << name << endl;
cout << "Next address3 is " << &name + sizeof name << " value at address is " << name + sizeof name << endl;
getchar();
}
y esta es la salida
-
Address2 es el valor 003EFAA4 en la dirección es Hello // fácil de entender.
-
La siguiente dirección 2 es 003EFAA8 (Aquí es donde me cuesta entender. Mi entendimiento es que la siguiente dirección debería ser 003EFAA5, considerando que el carácter es de 1 byte?
-
salida igual que 1
-
La siguiente dirección 2 es 003EFAB4 (Aquí es donde me cuesta entender también. Mi entendimiento es que la siguiente dirección debe ser 003EFAA8 cuando la dirección del nombre de la variable es 003EFAA4 considerando que el tamaño del puntero de caracteres es de 4 bytes.
Mi entendimiento sobre la memoria es que las direcciones están referenciadas en términos de bytes. Si eso es cierto, entonces ¿por qué en el número 3 de arriba me da la dirección que está 4 bytes más allá y en el número 4 de arriba me da la siguiente dirección que está 10 bytes más?
Cualquier explicación sería muy apreciada. Gracias
Bienvenidos a poith arithmetics.
char *name = "hello";
name
es un puntero a caracter
Almacena la dirección de
"hello"
cadena literal, es decir.
la dirección del carácter
h
(la dirección de una matriz es igual (al valor) de la dirección del primer elemento de una matriz).
Debes tener en cuenta que los literales de cadena son inmutables, no puedes modificarlos.
Así que es mejor cambiar el tipo a
const char*
.
&name
Este es un puntero al nombre de la variable.
No es un puntero a
"hello"
cadena literal, sino un puntero a un puntero.
El
003EFAA4
es la dirección de la variable de
name
.
La variable fue asignada por el compilador en la pila dentro de la función
main()
.
*(&name)
Los
*&
descartan (aquí) a sí mismos.
Entonces
*&name
es igual a
name
.
Esto imprime el valor del puntero del
name
, es decir.
este es el puntero al
"hello"
cadena literal, es decir.
este es el puntero al carácter
h
dentro de la cadena
"hello"
literal.
No
&name
.
Dirección del carácter
h
.
&name + 1
El
&name
tiene el tipo
char **
, es decir.
como un puntero a un puntero a un personaje.
Desde la aritmética de punteros, el
&name + 1
es igual al valor de
(uintptr_t)&name + 1 * sizeof(*&name)
.
sizeof(*&name)
es
sizeof(name)
es
sizeof(char*)
, por lo que es
(uintptr_t)&name + sizeof(char*)
.
En su arquitectura,
sizeof(char*)
es de 4 bytes (¿sistema de 32 bits?), Por lo que el puntero se incrementa en 4. Es decir.
003EFAA4 + 4 = 003EFAA8
.
name + 1
El
name
tiene el tipo de
char*
.
Desde el puntero aritmética
name + 1
es igual a
(uintptr_t)name + sizeof(*name)
.
sizeof(*name)
es
sizeof(char)
.
sizeof(char)
se define como igual a 1. Esto imprime la dirección de
e
char dentro de la cadena literal de
"hello"
.
&name + sizeof name
&name
tiene el tipo de
char**
, por lo que el valor de
&name
se incrementa
sizeof(name) * sizeof(char*) times. As
sizeof(name) * sizeof(char*) times. As
sizeof (nombre)
is equal to
sizeof (char *)
, this is
sizeof (char *) * sizeof (char *)
ie.
4 * 4 = 16` en su computadora.
name + sizeof name
Esto incrementa el valor del
name
del puntero por el valor de
sizoef(name) * sizeof(char)
.
sizeof(name)
es
sizeof(char*)
es
4
en su arquitectura,
sizeof(char)
es 1. Entonces
name + sizeof name
es la dirección del carácter
o
dentro del literal de la cadena
"hello"
, es decir.
003EFAA8
.
@edit reescrito algunas partes
Tienes uno demasiados niveles de direccionamiento indirecto aquí.
&name
es un char **, es decir, un puntero a un puntero de carácter.
Esto significa que si usted +1 agrega el tamaño de un puntero, no el tamaño de un carácter.
name
ya es un char *.
El problema entonces es hacer aritmética de punteros en nombre y luego imprimir la dirección del puntero usando cout en lugar de la cadena en el nuevo carácter *. Puedes hacer esto lanzando para anular *, por ejemplo
cout << "Next address2 is " << (void*)(name + 1)
utilizando moldes de estilo C.
&name
es de tipo
char**
.
La forma en que funciona la aritmética de punteros, si le agregas, aumenta el tamaño de
char*
(porque una
char**
apunta a una
char*
, y de esta manera apuntaría a la siguiente
char*
si hubiera una matriz de
char*
).
Parece que el tamaño de
char*
es
4
en tu sistema.
Entonces, si
&name
es
003EFAA4
, entonces
&name + 1
es
003EFAA8
(eso es
4
más).
sizeof name
es
4
, por lo que si lo agrega a
&name
, aumentará en
16
.
Por lo tanto, si obtiene
003EFAB4
, eso es
0x10
(o
16
) más que
003EFAA4
.