我是c ++的新手并尝试了一些东西。 所以最近我尝试在堆上创建一个int数组并使用地址迭代它而不是标准方式[x]。
每次执行我的代码时都会出现堆损坏错误。 我尝试了几件事(也在stackoverflow上搜索过),但找不到任何答案。
int* p = new int[5];
for (int i = 0; i <= 4; i++){
/*p[i] = i;
cout << p[i] << endl;*/ //This is the standard way and works
*p = i;
cout << *p << endl;
p = (p + sizeof(*p)); //iterate the pointer through the heap addresses
}
delete[] p;
应用程序运行并向我显示填充的数组值{0,1,2,3,4}但随后崩溃。
我收到以下错误消息:
HEAP CORRUPTION DETECTED:在CRT Block(#225)之后的0x00C31B68。 CRT检测到应用程序在堆缓冲区结束后写入内存...
提前致谢
答案 0 :(得分:4)
当你这样做时
p = (p + sizeof(*p));
你正在数组中采用sizeof(int)
个int大小的步骤,超出了它的范围。
您需要采取单一步骤:
p = (p + 1);
或
++p;
但请注意,执行该操作后,p
不再指向您可以拨打delete[]
的任何地方。您需要保留指向原始地址的指针:
int* arr = new int[5];
int* p = arr;
....
delete[] arr;
但您没有理由首先使用new
分配数组。
int arr[5];
int * p = arr;
....
答案 1 :(得分:2)
p = (p + sizeof(*p));
每次迭代都会导致4
跳跃,因为sizeof(int)
等于4
。因此,你将越界。
标准方式,即:
p[i] = i;
cout << p[i] << endl;
是正确的,因为i
在每次迭代中都会增加1
。
答案 2 :(得分:1)
本声明
p = (p + sizeof(*p));
错了。
首先,您要更改指针p的初始值,该值指向已分配的内存。所以此语句
delete[] p;
对于此指针是错误的,因为p的初始值已更改。
其次,表达式p + sizeof(*p)
表示您希望将指针向右移动到sizeof(* p)元素。例如,如果sizeof( *p )
等于4,则在语句
p = (p + sizeof(*p));
p将指向数组的第五个元素(即索引4)。
有效代码可以按以下方式查看
int* p = new int[5];
for ( int i = 0; i < 5; i++){
*( p + i ) = i;
cout << *( p + i ) << endl;
}
delete[] p;
答案 3 :(得分:1)
在指针算术中,表达式p + i
,其中p
是指向数组元素的指针,而i
是整数,等效到&(p[i])
,这是指向i
所指向的数组元素p
位置的指针。
这就是p = p+1
(或等价p += 1
或简称++p
)执行下一个元素的原因。
但是请注意,增量不会检查数组边界 - 如果它们属于同一个数组,您可以安全地访问的下一个项目。如果超出数组的最后一项,可能会出现内存访问错误,或者只是读取一些垃圾。
参见例如
http://www.tutorialspoint.com/cplusplus/cpp_pointer_arithmatic.htm
https://www.eskimo.com/~scs/cclass/notes/sx10b.html