我有一个C函数,它包含将实现字节码解释器的字节码的所有代码.
我想知道是否有办法在固定大小边界的内存中对齐已编译代码的段,以便我可以直接计算从字节码的值跳转到的地址?排序与数组的工作方式相同,但不是从计算的地址读取,而是跳到它.
我知道我必须把代码放在每个"字节码代码"段的末尾执行下一个跳转,并且我必须使边界大小至少与最大段的大小一样大.
如果这是可能的,我怎么告诉编译器/汇编器(gcc/g ++/as)以这种方式对齐?
我发现,艰难的方式,至少boost::program_options是依赖于编译器配置的结构成员对齐.
如果使用默认设置构建boost并使用4字节alignment(/Zp4)将其链接到项目,则它将在运行时失败(使用program_options进行最小测试).Boost将生成一个断言,指示可能的错误调用约定,但真正的原因是结构成员对齐.
有什么方法可以防止这种情况吗?如果对齐使得代码不兼容,那么它是否应该包含在库命名中?
我以为我理解C/C++如何处理结构成员对齐.但是我在Visual Studio 2008和2010中的特定安排中得到了奇怪的结果.
具体来说,我发现由char,short和char组成的结构被编译成6字节结构,即使启用了4或8字节打包.我不知道为什么会这样.我可以理解一个4字节的结构.我或许可以理解一个8字节的结构.但我认为当启用4字节打包时,6字节结构是不可能的.
一个演示问题的程序是:
#include <iostream>
using namespace std;
#pragma pack (4)
struct Alignment
{
char c1;
short s;
char c2;
};
#define REPORT_VAR_POSITION( structName, varName ) cout << "Member '" << #varName << "' sits at byte # " << offsetof( structName, varName ) << "." << endl;
int main(int argc, char* argv[])
{
cout << "Sizeof struct Alignment is " << sizeof( Alignment ) << " bytes." << endl;
REPORT_VAR_POSITION( Alignment, c1 );
REPORT_VAR_POSITION( Alignment, s ); …Run Code Online (Sandbox Code Playgroud) 你能看出他们这些地址中哪些是字对齐的吗?
0x000AE430
0X00014432
0X000B0737
0X0E0D8844
我正在处理一些分组数据.我创建了用于保存数据包数据的结构.这些结构是由python为特定的网络协议生成的.
问题在于,由于编译器对齐结构这一事实,当我通过网络协议发送数据时,消息最终会比我想要的更长.这会导致其他设备无法识别该命令.
有没有人知道可以解决这个问题,这样我的打包器的大小应该是结构的大小,还是有办法可以关闭内存对齐?
c compiler-construction gcc memory-alignment compiler-optimization
只是一个简单的问题......关于结构成员对齐的标准是什么?例如,这个:
struct
{
uint8_t a;
uint8_t b;
/* other members */
} test;
Run Code Online (Sandbox Code Playgroud)
保证b与struct start的偏移量为1?谢谢
我遇到了C#和C++之间的互操作问题,我通过本机代码和托管代码中定义的结构在应用程序的两个"端"之间共享内存.本机端的结构定义如下:
#pragma pack(push, 1)
struct RayTestCollisionDesc {
btVector3 hitPosition;
btRigidBody* hitBody;
RayTestCollisionDesc(btRigidBody* body, btVector3& position)
: hitBody(body), hitPosition(position) { }
};
#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)
并且在托管(C#)端定义了类似的结构.在C#上,结构大小是20个字节(正如我在32位系统上所期望的那样).但是,尽管有这个pragma pack指令,C++大小的结构大小仍然是32.为了清楚起见,这里sizeof()是每个类型的C++:
sizeof(btVector3) : 16
sizeof(btRigidBody*) : 4
sizeof(RayTestCollisionDesc) : 32
Run Code Online (Sandbox Code Playgroud)
显然pragma pack,只是指结构成员之间的打包,而不是结构末尾的填充(即对齐).我也试过添加,__declspec(align(1))但没有效果,MSDN本身确实说"__declspec(align(#))只会增加对齐限制."
FWIW我正在使用VS2013编译器(Platform Toolset v120).
有没有办法将结构大小"强制"为20个字节?
考虑以下计划:
#include <iostream>
class T {
char c;
int i;
};
int main() {
std::cout<<sizeof(T)<<'\n';
}
Run Code Online (Sandbox Code Playgroud)
8由于对齐,它将输出作为预期.C++编译器添加3个字节的填充.但如果我用D语言做同样的事情,它会给我完全意想不到的输出.(在这里查看现场演示.)
import std.stdio;
class T {
char c;
int i;
}
int main() {
writefln("sizeof T is %d",T.sizeof);
writefln("sizeof char is %d",char.sizeof);
writefln("sizeof int is %d",int.sizeof);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
sizeof T is 4
sizeof char is 1
sizeof int is 4
Run Code Online (Sandbox Code Playgroud)
sizeof(T)4怎么样?我期待得到8作为班级规模的输出. D编译器如何在这里执行对齐?我错了什么吗?我正在使用Windows 7 32位OS和Dmd编译器.
请考虑以下代码:
#include <iostream>
int main()
{
char* c = new char('a');
char ac[4] = {'a', 'b', 'c', 'd'};
unsigned long long int* u = reinterpret_cast<unsigned long long int*>(c);
unsigned long long int* uc = reinterpret_cast<unsigned long long int*>(&ac[3]);
*u = 42;
*uc = 42;
std::cout<<*u<<" "<<*uc<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
这被认为是有效的代码,还是内存泄漏/未定义的行为?我问,因为通过:
*u = 42;
*uc = 42;
Run Code Online (Sandbox Code Playgroud)
我们正在访问程序无法访问的字节(我猜).
我正在读一本关于" 理解和使用c指针 "的指针的书
说到void *它说
它有两个有趣的属性:
- 指向void的指针将具有与指向char的指针相同的表示和内存对齐.
令人困惑的是,所有指针的记忆都不一样吗?他们为什么而不是写void*与它明确提到的char指针的普通指针相同?真的很感激任何帮助