C语言中无法理解指针的内存地址结果

3
我在使用C语言的指针时遇到了一个令人困惑的问题。我已经进行了大量的搜索,但没有得到令我满意的答案。这就是问题所在:
我声明了一个INT类型的指针和一个INT类型的变量(例如int x,*pointer)。假设它们在RAM中占用连续的地址,比如0x102和0x106。到目前为止都没有问题。然后,我声明x = 5。我的内存映射应该是这样的,对吗?
int x, *pointer;
x = 5;

pointer1

好的。在大学里我学到了如何这样给指针赋值:

pointer = &x;

我的内存映射应该是这样的: pointer2 到目前为止都很好。但问题是:如果我不是像上面那样赋值指针,而是这样子:
*pointer = x;

“x”的内存地址不应存储在指针的内存地址中吗?我一直想知道类似于“Memory Map 2”这样的东西,但结果与“Memory Map 1”的结果相同,即0x106地址包含垃圾数字。那么,如果“x”的内存地址未存储在指针的内存地址中,程序如何知道我想要指向哪里?这些信息存储在哪里?
这看起来是一个简单的问题,但我无法理解。 :(
提前致谢! :)
4个回答

7

理解指针是有难度的。以下内容或许能帮到你。

你写道:

int x, *pointer;

这不仅仅是习惯用语,它告诉你一些重要的信息。它告诉你表达式x是“可以保存整数”的变量;这应该很清楚了。它还告诉你表达式*pointer也是“可以保存整数”的变量。

当你说

x = 123;

这意味着“将值123存储在变量x中”。因此,当您说
*pointer = 456;

这意味着“将值456存储在变量*pointer中”。当您说
pointer = &x;

那意味着“表达式*pointer——记住它是一个可以容纳整数的变量——与x相同”。它们是别名——同一个变量的两个名称。
所以你的问题是:
“如果x的内存地址未存储在指针的内存地址中,程序如何知道我想要指向哪里?”
让我用我已经建立的术语重新表述这个问题:
“如果我不初始化指针,程序如何知道*pointer引用哪个变量?”
它不知道。如果你说:
int x;
printf("%d", x);

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

int *pointer;
*pointer = 123;

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

现在清楚了吗?


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

4
int x, *pointer;
*pointer = x;

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

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

这句话的最后一行与x = x基本相同,因为pointer指向x

3

既然*是解引用运算符,那么你将尝试:

  • 存储x(因为没有地址of,在其名称之前没有&运算符)

  • 到由pointer指向的内存中(而不是指针本身,这毫无意义),这是不确定的,因为您的指针尚未初始化。

这并不是将x的地址存储到pointer中;你想要的仅通过写入pointer = &x;就可以实现,没有其他方法可以做到这一点。顺便说一下,由于在未初始化的指针所指向的内存中进行赋值,*pointer = x会导致未定义的行为。


2

*somePtr = someVar

这条语句将someVar的值赋给somePtr指向的位置。

为了更全面地说明,

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

x中的值赋给y。就是这样!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接