c++指针运算的怪异
C++ pointer arithmetic weirdness
我找到了我的bug(几个小时后),并在下面的程序中隔离了它。问题在于使用指向结构体的指针时计算pst2变量值的方式。当使用指针指向char时,一切正常。为什么会这样?
(使用gcc/g++版本:(Debian 4.4.5-8) 4.4.5)
(对于那些想知道的人:我正在访问一个包含常规偏移量的数据分组的文件缓冲区。)
#include <iostream>
#include "testpa.h"
#pragma pack(push)
#pragma pack(1)
//---------------------------
struct st_one
{
int i;
char c;
};
//---------------------------
struct st_two
{
long l;
int i;
};
#pragma pack(pop)
//===========================
int main()
{
int n=1024, np1=sizeof(st_one); //, np2=sizeof(st_two);
st_one *pst1, *pst1a;
st_two *pst2, *pst2a;
char *pc1, *pc2, *pc1a, *pc2a, *pb;
pb = new char[n];
pst1 = (st_one*)(pb);
pst2 = (st_two*)(pst1 + np1); //using pst1
pc1 = (char*)(pb);
pc2 = (char*)(pc1 + np1); //using pc1
pst1a = (st_one*)(pb);
pst2a = (st_two*)(pb + np1); //using pb
pc1a = (char*)(pb);
pc2a = (char*)(pb + np1); //using pb
std::cout << "npb = " << (long)pb;
std::cout << "n-----";
std::cout << "npst1 = " << (long)pst1 << "tpst2 = " << (long)pst2;
std::cout << "npc1 = " << (long)pc1 << "tpc2 = " << (long)pc2;
std::cout << "n-----";
std::cout << "npst1a = " << (long)pst1a << "tpst2a = " << (long)pst2a;
std::cout << "npc1a = " << (long)pc1a << "tpc2a = " << (long)pc2a;
std::cout << "n-----n";
return 0;
}
输出:pb = 19546128
pst1 = 19546128 pst2 = 19546153 <--- WRONG!
pc1 = 19546128 pc2 = 19546133
pst1a = 19546128 pst2a = 19546133
pc1a = 19546128 pc2a = 19546133
我看还行。线:
(pst1 + np1)
将st_one
的np1
个实例加到pst1
所指向的位置,这意味着pst1
的值增加了np1 * sizeof (st_one)
个字节,即25 (sizeof = 5),这与您输出的值相对应。我想你应该这样做:
(pst1 + 1)
pc1
值有效,因为它是一个char
指针,所以行:
(pc1 + np1)
在pc1
的基础上增加np1 * sizeof (char)
字节,即增加5字节。
指针的递增使指针指向内存中的下一个元素,而不是下一个字节
您不应该添加sizeof(x)
,因为这是自动完成的。当对指针进行自增操作(如++p)时,地址会随着对象的大小递增,从而指向下一个对象。
指针加1与++p相同。添加sizeof(x)
会将增量缩放两倍。
你的计算对char很好,因为sizeof(char)是1。
c++会自动将要添加的整数乘以指针所指向的元素的大小。
C和c++中的指针运算是乘以指针的指向类型sizeof
。也就是说,int *abc = /* ... */; int *def = abc + 1
导致def
在abc
之前有int
的结果,而不是char
。
至于将指针强制转换为long
s,这是实现定义的行为,因此在不同的机器上这样做可能会得到奇怪的结果。
(就此而言,指针类型之间的强制转换也是如此。c++说这也是实现定义的
看来你把一切都搞错了。例如,要从pst1获取pst2,您必须将其增加1,因为指针pst1
的类型是st_one *
,因此您必须这样写:
pst2 = (st_two*)(pst1 + 1);
. .但是你有:
pst2 = (st_two*)(pst1 + np1);
…其中np1是st_one
的sizeof
,所以它会跳过多少st_one
结构,因为该结构有多少字节…
阅读一些关于指针算术的文档,比如这个
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 避免指针运算,修复叮当整齐错误
- 如何在 c++ 中使用带有数学运算的引用/指针?
- 在标准布局对象中进行指针运算(例如,使用偏移量)时,我们是否需要使用 std::launder?
- 对已删除的数组进行指针运算仍然合法吗
- LLDB Python脚本中的指针运算
- C++中使用char*的指针运算
- 更正C中的指针运算
- 指针运算正在运行
- C++奇怪的指针运算
- T*与char*指针运算
- 指针运算在数组之外有用途吗?
- 我怎么知道是什么使不完整类型不完整的错误:对指向不完整类型的指针进行算术运算
- c++指针运算的怪异
- c++中auto_ptr的指针运算
- 调试断言失败!使用指针运算的字符串操作
- 限制限定符和指针运算
- std::uintptr_t可以用来避免指针越界运算的未定义行为吗?