【问题标题】:Doubts about pointer and memory access关于指针和内存访问的疑问
【发布时间】:2013-11-20 07:37:58
【问题描述】:

我刚刚开始学习 c 中的指针。我有以下几个疑问。如果我找到以下问题的答案。理解c中指针的概念对我来说非常有用。提前致谢。

我)

char *cptr;
int value = 2345;
cptr = (char *)value;

(char *) 的用途是什么,在上面的代码 sn-p 中是什么意思。

ii)

char *cptr;
int value = 2345;
cptr = value; 

这也编译没有任何错误。那么i和ii代码sn-p之间的区别是什么

iii) &value 是变量的返回地址。它是RAM中的虚拟内存地址吗?假设另一个 c 程序并行运行,该程序是否可以具有与&value 相同的内存地址。每个进程是否可以拥有与其他进程相同的重复内存地址并且相互独立?

iv)

#define MY_REGISTER (*(volatile unsigned char*)0x1234)

void main()
{
    MY_REGISTER=12;
    printf("value in the address tamil  is %d",(MY_REGISTER));
}

上面的sn -p 编译成功。但它输出分段错误错误。我不知道我在做什么错误。我想知道如何使用指针访问随机地址的值。有什么办法吗?程序真的会有地址 0x1234 吗?

v)printf("value at the address %d",*(236632));//consider the address 236632 available in

//stack

为什么上面的printf语句会报错?

【问题讨论】:

  • 第五点,“语句失败”是什么意思?
  • 第一个问题有错字;声明了cptr,但使用了ptr
  • 删除了 3 个与问题无关的标签。

标签: c pointers


【解决方案1】:
  1. 这是一个类型转换,它告诉编译器将一种类型视为其他(可能不相关的)类型。至于结果,见下文第2点。

  2. 这使得cptr 指向地址2345

  3. 现代操作系统隔离进程。一个进程中的一个变量的地址在另一个进程中是无效的,即使是用同一个程序启动的。事实上,由于Address Space Layout Randomisation (ASLR),第二个进程可能有完全不同的内存映射。

  4. 这是因为您尝试写入地址0x1234,这在某些系统上可能是有效地址,但在大多数系统上不是,而且几乎从不在运行例如 PC 的 PC 上。 Windows 或 Linux。

【讨论】:

  • 据我所知,每个正在运行的进程都认为它可以完全访问整个内存(RAM)。让我们说两个进程 Aprocess,Bprocess,考虑一个地址位置 0x0000,Aprocess 和 Bprocess会有单独的 0x0000 虚拟地址吗?如果我错了,请纠正我。谢谢
  • @tamil_innov 这就是虚拟地址的意义所在,它不必与物理地址相同。在具有交换空间的系统上,地址甚至不必在物理内存中。此外,即使同一个程序的两个进程碰巧有相同的内存映射,它仍然是两个不同的进程,有两个独立的内存映射,有两个独立的分配。进程之间不共享内存。
  • @JoachimPileborg:这有点强。特别是,用于代码的内存通常是共享的。反正它是只读的。
【解决方案2】:

我)

(char *) 表示将存储在value 中的数据转换为指向char 的指针ptr。这意味着,ptr 指向内存位置 2345。在您的代码片段中,ptr 是未定义的。我猜那个程序里还有更多。

ii)

不同之处在于,您现在写入 cptr,它是(如您所定义的)指向 char 的指针。与 i) 中没有太大区别,只是您写入不同的变量,并且使用了隐式强制转换,这由编译器解决。同样,cptr 现在指向位置 2345 并期望有一个 char

iii)

是的,你可以说它是一个虚拟地址。分段在这个游戏中也扮演了一些角色,但在你的阶段你根本不需要担心它。操作系统会为您解决这个问题,并确保您只覆盖程序专用内存空间中的变量。因此,如果您同时运行一个程序两次,并打印一个指针,它很可能是相同的值,但它们不会指向内存中的相同值。

iv)

一开始没有看到写指令。您不能只将任何地方写入内存,因为您可能会覆盖另一个程序的值。

v)

与上述类似的问题。你不能只是取消引用任何你想要的数字,你首先需要将它转换为一个指针,否则编译器、你的操作系统和你的 CPU 都不会知道它到底指向什么

希望我能帮助你,但我建议你再次深入阅读一些关于 C 指针的书籍。

【讨论】:

    【解决方案3】:

    i.) Type cast,您将整数转换为字符

    ii.) 你指向的地址是 2345。

    iii.) 请参阅 Joachim Pileborg 的回答。 ^ASLR

    iv.) 你不能在不知道 / 中是否已经存在某些东西的情况下直接写入地址。

    v.) 因为您实际上是在使用指针来打印一个普通整数,这应该会引发错误 C2100: illegal indirection

    【讨论】:

      【解决方案4】:

      您可能会将指针视为邮箱上的数字。当您为指针设置值时,例如 cptr = 2345 就像您移动到邮箱 2345 前面一样。没关系,与内存没有实际交互,因此不会崩溃。当您声明 *cptr 之类的内容时,这指的是实际的“邮箱内容”。为 *cptr 设置一个值就像试图在你面前的邮箱中放一些东西(内存位置)。如果您不知道它属于谁(应用程序如何使用该内存),那可能是个坏主意。您可以使用“malloc”来初始化指针/分配内存,并在完成工作后使用“free”来清理。

      【讨论】:

        猜你喜欢
        • 2011-11-26
        • 2016-08-05
        • 2021-06-15
        • 1970-01-01
        • 2010-12-13
        • 2020-10-20
        • 1970-01-01
        • 2011-12-09
        • 2023-03-21
        相关资源
        最近更新 更多