为什么不能为指针分配内存地址号?

时间:2020-07-24 03:25:18

标签: c++ pointers

我们知道一个指针有一个名称和一个值,本质是变量,值是十六进制数,它是一个内存地址。

int a = 10;
int * p = &a;

cout << p << endl;  // 0x7ffee04fe2b8

int * q = 0x7ffee04fe2b8;  // why can not assign address number to the pointer `q`?

image


如果我分配了0x0,它将起作用:

int * q = 0x0;

0x0引用NULL,无论是由于解释程序进行特殊处理还是如此。

我使用CLion编辑器。


编辑

我试图声明为long,也遇到了问题:

image


编辑

我使用64位macOS。

指针值存储一个内存地址,因此我想尝试直接分配该地址。为什么我不能使用这种方法?

int a = 10;
int * p = &a;

cout << p << endl;  // 0x7ffee04fe2b8

long q = 0x7ffee04fe2b8;
cout << * (int *)q << endl;  // prints nothing

编辑

我尝试了这篇文章:Pointer to a specific fixed address

int a = 10;
int * p = &a;

cout << p << endl;  // 0x7ffee04fe2b8

volatile unsigned int *myPointer = (volatile unsigned int *)0x7ffee04fe2b8;

cout << *myPointer << endl;  // print nothing

但是为什么不打印任何东西?

它构建成功,但是当我运行它时,它用*myPointer不打印任何内容。

====================[ Build | untitled | Debug ]================================
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build /Users/luowensheng/CLionProjects/untitled/cmake-build-debug --target untitled -- -j 4
[100%] Built target untitled

Build finished

2 个答案:

答案 0 :(得分:2)

在C语言中,您 CAN 从常量中分配地址。这不是一个好主意。但是你可以做到的。

示例编译器错误:

$ cat c-ptr-test.c
int main() {
  long *p = 0x0011223344556677;
  return 0;
}
$ make c-ptr-test
cc -Wall -W -pedantic -g -O3 -flto -fno-fat-lto-objects -pthread -MMD  -std=c11   -pthread -flto -fno-fat-lto-objects  c-ptr-test.c   -o c-ptr-test
c-ptr-test.c: In function ‘main’:
c-ptr-test.c:2:13: warning: initialization of ‘long int *’ from ‘long int’ makes pointer from integer without a cast [-Wint-conversion]
    2 |   long *p = 0x0011223344556677;
      |             ^~~~~~~~~~~~~~~~~~
c-ptr-test.c:2:9: warning: unused variable ‘p’ [-Wunused-variable]
    2 |   long *p = 0x0011223344556677;
      |         ^

两个警告,但GCC编译成功。

但是,在C ++语言中,它需要显式强制转换。您应该使用reinterpret_cast,但也可以使用旧的C样式强制转换。

答案 1 :(得分:0)

似乎您正在尝试分配指针,而没有告诉编译器您“想要”分配指针。

您的编译器错误应类似于this

从“ long int”到“ int *”的无效转换

要分配地址,语法应为int *q = (int*)0x7ffee04fe2b8;,而(int*)表示“此值是指针int*的地址。

或更现代的方式:int * q = reinterpret_cast<int*>( 0x7ffebfc7019c );

但是您必须知道您在做什么。除非您使用硬件寄存器对低级代码进行编码,否则请不要对地址进行硬编码。

同样,每次执行代码时,其地址都可能与上次不同。

尝试以下代码:或在GCC 10.1 https://godbolt.org/z/8zn7j5

int main()
{
   int a = 10;
    int * p = &a;

    cout << p << endl;

    long addr = (long)p;
    int * q = reinterpret_cast<int*>( addr );
    cout << *q << endl;
    return 0;
}