给指针赋值

新手上路,请多包涵

我在理解指针的概念时遇到了一些麻烦,其中之一是:

让我们声明一个整数类型变量 n 和一个指向它的指针 *p。

int n=23,*p;

现在,

p=&n; 如果我没记错,将变量 n 的地址(比如 3000)分配给 p。

所以 cout<<p<<" "<<*p; 将分别输出 3000 和 23。

我的疑问是假设我们做了这样的事情:

p=5; 即为 _设计用于保存内存位置的变量分配一个数值_,会发生什么?

变量是移动到内存位置’5’(很可能不是)还是指针刚刚转换为’int’并保持值5?我会自己尝试一下,只是弄乱了我的系统内存让我重新考虑。

另外,当我们声明任何变量时(假设 int 有 2 个字节空间),它是存储在 3000、101、2700 之类的随机内存位置,还是存储在 0、2、4 等?声明的下一个变量是否存储在下一个变量中(如 3002、103 或 2702),或者两者之间是否存在某种间隙?

原文由 Anchith Acharya 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 609
2 个回答

在您的示例中,这是一个编译器错误。

但是,我假设您想要做的是:

 int n =23, *p;
p = &n;
//Change the value of p to 3000, p now points to address 3000
p = reinterpret_cast<int*>(3000);
//Check if the address of n has changed
std::cout << "Address of n : " << reinterpret_cast<int>(&n) << std::endl;

正如您在运行此代码时所知道的那样。 n 的地址不变。

对于你的第二个问题。

是和否:)

如果您定义两个彼此相邻的变量,它们在内存中 可能 彼此相邻。

  int a,b,c,d;
 char c = 1;
 short s = 1;
 void* p = nullptr;
 int i = 1;

 std::cout << "a is at: " << reinterpret_cast<int>(&a) << std::endl;
 std::cout << "b is at: " << reinterpret_cast<int>(&b) << std::endl;
 std::cout << "c is at: " << reinterpret_cast<int>(&c) << std::endl;
 std::cout << "d is at: " << reinterpret_cast<int>(&d) << std::endl;
 std::cout << "Char is at: " << reinterpret_cast<int>(&c) << std::endl;
 std::cout << "Short is at: " << reinterpret_cast<int>(&s) << std::endl;
 std::cout << "Pointer is at: " << reinterpret_cast<int>(p) << std::endl;
 std::cout << "Int is at: " << reinterpret_cast<int>(&i) << std::endl;

这种行为是由编译器决定在哪里粘贴everthting。它可能彼此相邻,也可能不存在。如果要保证它们彼此相邻,请使用数组。

 int arr[] = {1,2,3,4,5,6,7};
int * p = &arr[0]; //get address of first element
for(int i = 0 ; i < 7; ++i)
    std::cout << "Value at address: " << reinterpret_cast<int>(p+i)
        << " is: " << *( p + i) << std::endl;

原文由 user3853544 发布,翻译遵循 CC BY-SA 3.0 许可协议

假设您通过添加强制转换使其编译

p=(int *)5;

然后取消引用该指针将是未定义的行为。它可以做任何事情,但您的程序很可能会中止。它可以在不同的系统上表现不同。

此外,变量或下一个获得的地址也取决于您运行程序的系统。大多数系统为局部变量使用堆栈,但它们可以向上或向下计数,所以你不知道。

调试和优化构建也可以发出不同的代码。一些编译器会在局部数组或变量之后留出空间,因此当您在数组外写入时它们会给出有意义的错误。但是在发布时,他们可能会尽可能地使用内存。

为了使事情变得更加不可预测,主流操作系统有一种称为地址空间布局随机化 (ASLR) 的技术。

https://en.wikipedia.org/wiki/Address_space_layout_randomization

每次程序运行时,变量获得的基地址都会随机化。这样黑客就不能滥用缓冲区溢出并在他们注入自己的代码的地方再计算返回地址。

所以不,你不能说关于变量地址的任何一般性内容。您必须检查您的编译器和操作系统。

原文由 Serve Laurijssen 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏