【问题标题】:c++ array of pointers and memory address allocationc++ 指针数组和内存地址分配
【发布时间】:2020-08-15 09:01:21
【问题描述】:

谁能解释一下c++的指针数组是如何动态实现的?

下面的代码正确吗?

如果是这样,

 int *ptr[5]; 

 for (int i = 0; i < 5; i++)
  {

  int size = 2;

  ptr[i] = new int [size] ;

 //*(ptr + i) = new int[size]; this is the same as above line

  cout << &ptr[i] << endl;   ----------> line 1
  cout << ptr[i] << endl; -----------> line 2
  }

第 1 行和第 2 行实际打印的是什么?

这是我在第 1 行得到的地址

0x7fff88f805d0
0x7fff88f805d8
0x7fff88f805e0
0x7fff88f805e8
0x7fff88f805f0

这是我在第 2 行得到的地址

0x55f946348ef0
0x55f946349330
0x55f946349360
0x55f946349390
0x55f9463493c0

有人能解释一下这堆指针数组吗?

【问题讨论】:

  • 每个数组中的元素在这两种情况下似乎都是等距的。你认为78 与十六进制的80 相差多远?
  • int *ptr[i] = new int[10]; no... 你声明int *ptr [5];(五个指针),在你的循环中你想要ptr[i] = new int[10];[..] 本身就是一个取消引用,例如*(ptr + i).
  • 嗯,地址似乎暗示了这些项目是按某种顺序分配的。但是,它们更有可能是随机的并且来自随机存储器。在您的情况下,该程序是“新鲜的”,因此它们似乎有订单,但实际上,每个“新”都可能返回与任何其他“新”无关的东西。大小不完全匹配,因为“新”在分配和取消分配项目时有自己的开销。此外,一些编译器需要担心对齐问题,这会再次混淆选择特定地址的原因及其表观大小。
  • @cigien,我明白了,感谢您指出十六进制混淆,我编辑了问题。你能向我解释一下什么地址吗,我在编辑后的问题的第 2 行。这是什么意思?

标签: c++ arrays oop pointers memory-address


【解决方案1】:

图片提供了问题的图形解释,如果有人得到 与指针数组概念混淆,将指针数组动态分配给新 int 或任何其他类型数组


int *ptr[2]; // statically declared pointer array stack

    int p [2];

for (int i = 0; i < 2; i++)
      {
      int size = 2;

      ptr[i] = new int[size];
      cout << i << " array of int " << endl;
      //*(ptr + i) = new int[size];

      for (int j = 0; j < size; j++)
        {
        cout << "value : " ;
        cout << *(ptr[i] + j) ;  // <------- this should give 0's as value
        //cout << (ptr[i])[j] ; <------ same thing
        cout << "  address :";
        cout << ptr[i] + j << endl; //<----- these are in order as well since it's an array of type int

        }

      }
0 array of int 
value : 0  address :0x564c9ede32c0
value : 0  address :0x564c9ede32c4
value : 0  address :0x564c9ede32c8
1 array of int 
value : 0  address :0x564c9ede32e0
value : 0  address :0x564c9ede32e4
value : 0  address :0x564c9ede32e8

【讨论】:

    【解决方案2】:

    我假设您想对动态数组执行操作,例如添加元素和打印; 记住:在 int *ptr=new int[5]; sizeof(ptr) 在栈内存中为 8 个字节,数组将存储在堆内存中。

    我们将通过指针 ptr 获取元素,每个元素都将根据数组类型(比如 int )获取,然后 ptr 将转到第 0 个索引元素并以 int 类型读取它的数据(只有 4 个字节,因为 int 是通常为 4 字节)并移动到下一个索引直到结束。 查看下面的代码:

    #include <iostream>
    using namespace std;
    
    int main() {
    int *ptr=new int[5]; //let size = 5
    for(int i=0; i<5;i++){
    cin>>ptr[i];
    }
    for(int i=0; i<5;i++){
    cout<<&ptr[i]<<":";  //this will print every element's address per iteration
    cout<<ptr[i]<<endl;  //this will print every element as per input you gave
    }
    delete []ptr; //remember it's not delete ptr ask if required
    return 0;
    }
    

    现在看看输出,自己试运行你就可以理解了

    输出

    0x556999c63e70:1
    0x556999c63e74:2
    0x556999c63e78:3
    0x556999c63e7c:4
    0x556999c63e80:5
    

    动态数组的好处是您可以根据用户选择通过输入大小来创建动态大小的数组,该变量是动态数组的大小 即您可以将 size=5 以上更改为 'N' 一个变量。

    我认为这可能会对您有所帮助,否则您可以要求进一步澄清。

    【讨论】:

    • int *ptr[5]; 我想弄清楚的是这个,以及它是如何扩展的
    • 这不是制作一维动态数组的正确方法......因为它包含 5 个没有意义的地址......
    • 如果你想将指针(很多)存储到另一个指针(单个)中,那么当你需要二维数组时这将是有意义的......你可以访问几个 cpp 的参考网站,你彻底搞定!
    • 我想要一个可以包含另一组数组的数组,这确实是 int* 类型的数组,我想我在画了一点之后就知道了。第一个数组(int * 类型)存储在堆栈中,下一个数组(int 类型)存储在堆中。
    猜你喜欢
    • 1970-01-01
    • 2012-03-15
    • 2019-04-07
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    相关资源
    最近更新 更多