【问题标题】:Can't understand pointer's mem address result in C无法理解指针的内存地址导致 C
【发布时间】:2013-05-11 14:58:28
【问题描述】:

我对 C 语言中指针的使用产生了令人震惊的疑问。因此,我对此进行了很多搜索,但没有得到令人满意的答案。事情是这样的:

我声明了一个 INT 类型的指针和一个 INT 类型的变量(例如 int x、*pointer)。因此,我们假设它们都占用了 RAM 中的连续地址,分别为 0x102 和 0x106。到目前为止没有任何惊喜。然后,我声明 x = 5。我的内存映射应该是这样的,不是吗?

int x, *pointer;
x = 5;

好的。在大学里我学会了这样分配指针:

pointer = &x;

而我的内存映射应该是这样的:

到目前为止一切顺利。但问题是:如果我分配的不是上面的指针,而是这样的:

*pointer = x;

'x'的内存地址不应该存储在指针的内存地址中吗?我一直在想“Memory Map 2”之类的东西,但结果和“Memory Map 1”一样,即0x106地址包含一个垃圾号。那么如果'x'的内存地址没有存储在指针的内存地址中,程序如何知道我想指向的位置呢?这些信息存储在哪里?

这似乎是一个简单的问题,但我无法理解。 :(

提前致谢! :)

【问题讨论】:

    标签: c pointers


    【解决方案1】:

    了解指针的工作方式很棘手。这可能会有所帮助。

    你写的

    int x, *pointer;
    

    这不仅仅是惯用的;这告诉你一些重要的事情。它告诉你表达式x一个可以容纳整数的变量;希望这很清楚。它还告诉您表达式*pointer 也是一个可以保存整数的变量

    当你说

    x = 123;
    

    这意味着“将值 123 存储在变量 x 中”。

    所以当你说

    *pointer = 456;
    

    这意味着“将值 456 存储在变量 *pointer 中”。

    当你说

    pointer = &x;
    

    这意味着“表达式*pointer——记住是一个可以保存整数的变量——与x是同一个变量”。它们是别名——同一个变量的两个名称。

    所以你的问题是:

    如果x 的内存地址未存储在指针的内存地址中,程序如何知道我想指向的位置?

    让我用我已经建立的术语重新表述这个问题:

    如果我不初始化pointer,程序怎么知道*pointer指的是哪个变量?

    它不知道。如果你说:

    int x;
    printf("%d", x);
    

    然后你可以得到 any 整数打印;这是未定义的行为。你还没有说你希望变量x 有什么值,所以它可以有任何值。当你说:

    int *pointer;
    *pointer = 123;
    

    然后你说“将123 存储在变量*pointer 中”,但你还没有说*pointer 是什么变量。所以,就像x 可以有任何值一样,*pointer 可以是任何变量。同样,我们有未定义的行为。

    现在清楚了吗?

    【讨论】:

    • 非常感谢您的回答。所以,为了确保我理解你所说的,让我再举一个例子:int x, *pointer;pointer = (int *)malloc(sizeof(pointer)); 根据定义,如果我 printf("%d", *pointer),这个指令应该打印包含的地址的内容&pointer里面,也就是垃圾吧?
    • 当我尝试这样做时,我产生了疑问:*pointer = 5(例如)。 IMO,我应该得到一个错误,因为我试图将值“5”放在 &pointer 中包含的内存地址中。相反,代码在“代码块”中没有警告(我预计会出现分段错误)。以这种方式思考指针我错了吗?我对指针的主要定义是错误的?在此先感谢您的帮助! :)
    • @user2373016:“未定义的行为”意味着任何事情都可能发生。段错误包含在“任何内容”中。 所以没有段错误。当您做错事时,系统并不要求给您一个段错误;相反,你必须做正确的事
    • @user2373016:至于你的“初级定义”有没有错,我不知道,因为我不知道是什么。我鼓励你像我一样思考指针;指针是当您将* 放在它前面时,它会为您提供一个变量——一个可以存储某些东西的位置。其他一切——所有这些关于指针是内存地址之类的东西——都是你可以忽略的实现细节。指针不一定是地址,它只需要在你取消引用它时给你一个变量。
    • Lipert:再次感谢您的帮助!我得到了它。 []的
    【解决方案2】:
    int x, *pointer;
    *pointer = x;
    

    这是未定义的行为,因为pointer 没有指向有效的内存位置。

    int x, *pointer;
    x = 5;
    pointer = &x;
    *pointer = x;
    

    这最后一行和x = x基本一致,因为pointer指向x

    【讨论】:

      【解决方案3】:

      由于* 是取消引用运算符,那么您将尝试:

      • 存储x(因为它的名字前没有addressof,&运算符)

      • 指向由 pointer 指向的内存(并且指向指针本身,这无论如何都没有意义),这是不确定的,因为您的指针尚未初始化。

      这不是将x的地址存入pointer;你想要的只能通过写pointer = &x;来实现,没有其他方法可以做到这一点。顺便说一句,由于分配给未初始化指针指向的内存,*pointer = x 调用未定义的行为。

      【讨论】:

        【解决方案4】:

        在做

        *somePtr = someVar

        somePtr 指向的位置分配somevar 的值..

        为了更全面,

        int x = 2, y =3;
        int * pointer;
        pointer = &x;
        *pointer = y;
        

        y 的值分配到x 中。就是这样!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-03
          • 2015-04-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-08-22
          相关资源
          最近更新 更多