带地址的 C++ 数组迭代 - 堆损坏
c++ array iteration with addresses - heap corruption
我是 c++ 的新手,正在尝试一些东西。
所以最近我尝试在堆上创建一个 int 数组并使用寻址而不是 [x].
的标准方式对其进行迭代
每次执行我的代码时,我都会收到堆损坏错误。
我尝试了几件事(也在 Whosebug 上搜索过)但找不到任何答案。
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} 但随后崩溃。
我收到以下错误消息:
检测到堆损坏:在 0x00C31B68 处的 CRT 块 (#225) 之后。
CRT 检测到应用程序在堆缓冲区结束后写入内存...
提前致谢
当你这样做时
p = (p + sizeof(*p));
您正在对数组执行 sizeof(int)
整数步,超出了数组的范围。
您需要单步执行:
p = (p + 1);
或
++p;
但请注意,在这样做之后,p
不再指向您可以调用 delete[]
的任何地方。您需要保留指向原始地址的指针:
int* arr = new int[5];
int* p = arr;
....
delete[] arr;
但是你没有理由首先分配new
数组。
int arr[5];
int * p = arr;
....
p = (p + sizeof(*p));
导致每次迭代跳转 4
,因为 sizeof(int)
等于 4
。因此,您将越界。
标准方式,即:
p[i] = i;
cout << p[i] << endl;
是正确的,因为 i
在每次迭代中增加 1
。
这条语句
p = (p + sizeof(*p));
错了。
首先,您要更改指向分配的指针 p 的初始值 memory.So 此语句
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;
在指针运算中,表达式 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
我是 c++ 的新手,正在尝试一些东西。 所以最近我尝试在堆上创建一个 int 数组并使用寻址而不是 [x].
的标准方式对其进行迭代每次执行我的代码时,我都会收到堆损坏错误。 我尝试了几件事(也在 Whosebug 上搜索过)但找不到任何答案。
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} 但随后崩溃。
我收到以下错误消息:
检测到堆损坏:在 0x00C31B68 处的 CRT 块 (#225) 之后。 CRT 检测到应用程序在堆缓冲区结束后写入内存...
提前致谢
当你这样做时
p = (p + sizeof(*p));
您正在对数组执行 sizeof(int)
整数步,超出了数组的范围。
您需要单步执行:
p = (p + 1);
或
++p;
但请注意,在这样做之后,p
不再指向您可以调用 delete[]
的任何地方。您需要保留指向原始地址的指针:
int* arr = new int[5];
int* p = arr;
....
delete[] arr;
但是你没有理由首先分配new
数组。
int arr[5];
int * p = arr;
....
p = (p + sizeof(*p));
导致每次迭代跳转 4
,因为 sizeof(int)
等于 4
。因此,您将越界。
标准方式,即:
p[i] = i;
cout << p[i] << endl;
是正确的,因为 i
在每次迭代中增加 1
。
这条语句
p = (p + sizeof(*p));
错了。
首先,您要更改指向分配的指针 p 的初始值 memory.So 此语句
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;
在指针运算中,表达式 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