C++ Memory Address

Fai*_*han 6 c++ memory

Please excuse me if this is a repeated question

This is my code

#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();
}
Run Code Online (Sandbox Code Playgroud)

and this is the output

  1. Address2 is 003EFAA4 value at address is Hello // easy for me to understand

  2. 下一个地址2是003EFAA8(这是我很难理解的地方。我的理解是,考虑到char是1字节,下一个地址应该是003EFAA5?

  3. 输出与1相同

  4. 下一个Address2003EFAB4(这也是我也很难理解的地方。我的理解是,当变量名称的地址为003EFAA4时,考虑到char指针的大小为4字节,下一个地址应为003EFAA8?

我对内存的理解是地址是以字节为单位引用的。如果是这样,那么为什么在上面的数字3中又给我提供了另外4个字节的地址,而在上面的数字4中又给了我下一个又是10个字节的地址呢?

任何解释将不胜感激。谢谢

Nat*_*ica 9

下一个地址2是003EFAA8(这是我很难理解的地方。我的理解是,考虑到char是1字节,下一个地址应该是003EFAA5?

执行此操作时,&name + 1您将转到类型为的下一个地址namename不是char。它是一个,char*并且在您的系统上a char*的大小为4。这就是为什么它向前4个字节的原因,因为这是下一个char*可以定位的地方。

下一个Address2是003EFAB4(这也是我也很难理解的地方。我的理解是,当变量名称的地址为003EFAA4时,考虑到char指针的大小为4字节,下一个地址应为003EFAA8?

这基本上与上面发生的事情相同,但是除了转到下一个元素外char*,您将转到sizeof name下一个元素,在这种情况下,它是第四个元素。


Bla*_*aze 7

&name是类型char**。指针算术的工作方式(如果添加)会使其大小增加很多倍char*(因为char**指向char*,并且char*如果存在,它将指向下一个char*)。它看起来像的大小char*就是4你的系统上。因此,如果&name003EFAA4,则&name + 1003EFAA84更多)。

sizeof name4,因此,如果您添加它,&name则增加16。因此乳清你003EFAB4,那0x10(或16)以上003EFAA4


Kam*_*Cuk 6

欢迎使用指针算法。

char *name = "hello";
Run Code Online (Sandbox Code Playgroud)

name是指向字符的指针。它存储"hello"字符串文字的地址,即。字符h的地址(数组的地址等于(等于值)数组的第一个元素的地址)。您应该注意,字符串文字是不可变的,您无法对其进行修改。因此,最好将类型更改为const char*

&name
Run Code Online (Sandbox Code Playgroud)

这是指向变量名的指针。不是指向"hello"字符串文字的指针,而是指向指针的指针。该003EFAA4是地址name变量。变量是由编译器在main()函数内部的堆栈上分配的 。

*(&name)
Run Code Online (Sandbox Code Playgroud)

*&规则(在这里)自己出。因此*&name等于name。这将打印name指针的值,即。这是"hello"字符串文字的指针,即。这是指向字符串文字h内部"hello"字符的指针。不&nameh字符地址。

&name + 1
Run Code Online (Sandbox Code Playgroud)

&namechar **型,即。它作为指向字符的指针的指针。根据指针算术,the &name + 1等于to的值(uintptr_t)&name + 1 * sizeof(*&name)sizeof(*&name)sizeof(name)sizeof(char*),所以(uintptr_t)&name + sizeof(char*)。在您的体系结构上sizeof(char*)是4字节(32位系统?),因此指针增加了4。003EFAA4 + 4 = 003EFAA8

name + 1
Run Code Online (Sandbox Code Playgroud)

name具有的类型char*。从指针算术name + 1等于(uintptr_t)name + sizeof(*name)sizeof(*name)sizeof(char)sizeof(char)被定义为等于1。这将e"hello"字符串文字中打印char 的地址。

&name + sizeof name
Run Code Online (Sandbox Code Playgroud)

&name的类型为char**,因此在您的计算机上,值的值&name是递增sizeof(name) * sizeof(char*) times. Assizeof(name)is equal tosizeof(char *), this issizeof(char *)* sizeof(char *)ie.4 * 4 = 16`。

name + sizeof name
Run Code Online (Sandbox Code Playgroud)

这会将指针name值增加的值sizoef(name) * sizeof(char)sizeof(name)sizeof(char*)4你的体系结构,sizeof(char)为1所以name + sizeof name是一个字符的地址o"hello"字符串常量,即。003EFAA8

@edit重写了一些部分


Rup*_*Rup 5

您在这里拥有太多的间接级别。

&name是一个字符**,即指向字符指针的指针。这意味着,如果您+1,那么您将添加指针的大小,而不是字符的大小。name已经是一个字符*。

然后问题是对名称进行指针算术运算,然后使用cout而不是新char *处的字符串打印指针地址。您可以通过强制转换为void *来做到这一点,例如

cout << "Next address2 is " << (void*)(name + 1)
Run Code Online (Sandbox Code Playgroud)

使用C样式转换。