我有两个代码:
正常:
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中的所有元素都指向正常声明的相同位置,而在动态声明中创建了多个对象?
这是为什么?
答案 0 :(得分:5)
在第一种情况下,所有条目都指向s
,并且在s
超出范围时保持悬空状态。解除引用p[i]
会导致未定义的行为。
在第二种情况下,每个条目都指向一个单独的堆分配对象。这里没有未定义的行为(但是存在内存泄漏)。
答案 1 :(得分: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);
}
答案 2 :(得分:1)
在第一种情况下,在每次迭代中,您在堆栈上分配一个整数,然后将此地址分配给该数组。
由于堆栈上没有其他变量,s
总是在堆栈上的同一地址上分配,最终所有p
元素指向同一地址,其中包含最后一个随机值,即7.除此之外,退出循环后,您不知道可以写入此地址的内容,因为在离开s
范围后,编译器可以使用相同的地址来存储其他数据。你可以通过在循环之外移动int s
来防止这种情况,但你仍然会将p
的所有元素指向同一个堆栈地址。
在第二种情况下,在每次迭代中在堆上分配一个新的整数,因此p
指向5个不同的对象/地址