3

我有两个代码:
正常:

int* p[5];
for (int i=0;i<5;i++){
    int s = rand()%25;
    p[i]=&s;
}

动态的:

int* p[5];
for (int i=0;i<5;i++){
    int* s = new int;
    *s = rand()%25; //Edit: typo, I didn't want to make a random pointer
    p[i]=s;
}

现在,如果我先打印数组 p,p[i]然后:*p[i]在它之后,我得到:

 static             dynamic
0x22ff04 7         0x22ff30 7
0x22ff04 7         0x22ff24 14
0x22ff04 7         0x22ffa6 2
0x22ff04 7         0x22ff89 8
0x22ff04 7         0x22ff13 21

现在为什么 p 中的所有元素都指向正常声明的同一位置,而在动态声明中创建了多个对象?
为什么是这样?

4

3 回答 3

6

在第一种情况下,所有条目都指向并在超出范围s的那一刻悬空。s取消引用p[i]会导致未定义的行为。

在第二种情况下,每个条目都指向一个单独的堆分配对象。在这里,没有未定义的行为(但存在内存泄漏)。

于 2013-03-04T14:42:14.457 回答
4

我偷偷怀疑你想要一个随机值数组:

#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    std::srand(time(0)); // Don't forget to seed!

    std::vector<int> v(5);
    std::generate(v.begin(), v.end(), random);

    // or
    std::vector<int> w;
    std::generate_n(std::back_inserter(w), 5, random);
}
于 2013-03-04T14:47:41.633 回答
1

在第一种情况下,在每次迭代中,您在堆栈上分配一个整数,然后将此地址分配给数组。由于堆栈上没有其他变量,s因此总是分配在堆栈上的同一地址上,并且您最终会得到p指向同一地址的所有元素,该地址包含最后一个随机值,即 7。除此之外,退出后循环,您不知道可以向该地址写入什么,因为离开范围后s,编译器可以使用相同的地址来存储其他一些数据。您可以通过移出循环来防止这种int s情况发生,但您仍然可以让所有元素p指向相同的堆栈地址。

在第二种情况下,您在每次迭代中在堆上分配一个新整数,因此p指向 5 个不同的对象/地址

你想达到什么目的?

于 2013-03-04T14:44:25.997 回答