2

考虑以下 Objective-C++ iPhone 应用程序 (TestMemAppDelegate.mm)。它在 iPhone 上以 EXC_BAD_ACCESS 崩溃(3GS 与 iOS 4.0)。它在模拟器中运行良好。这显然是一个内存对齐的事情,因为如果“DataA”结构从 8 字节边界开始,它在 iPhone 上可以正常工作。

谁能解释原因?它与ARM架构有关吗?ARM编译器?

@implementation TestMemAppDelegate


typedef struct DataA
{
 float    x;
 unsigned char  y;
};


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

 char* mem1 = (char*)malloc(4096);

 DataA* ptrA = (DataA*)(mem1 + 1); // Here we shift the alignment
 ptrA->x = 10.0f;
 printf("A: %.2f\n", ptrA->x); // Here it crashes



    // Add the view controller's view to the window and display.
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    return YES;
}


@end
4

3 回答 3

6

是的,这是一个对齐问题。浮点数需要 4 字节对齐。Intel x86 CPU 允许未对齐的访问(但会降低性能)。在 ARM 上,这是不允许的,并会生成您看到的错误。

于 2010-08-09T11:05:58.423 回答
0

浮点数通常必须至少 4 字节对齐。

于 2010-08-09T10:31:50.447 回答
0

我想你会发现它违反了 C(可能是 C99)标准。malloc() 保证返回适当对齐的内存,因此您可以执行类似的操作

struct DataA * foo = (struct DataA *)malloc(sizeof(struct DataA));
foo->x = 10;

但是,有对齐要求,因此不能保证您可以任意修改指针并使其仍然有效。

也就是说,操作系统可以通过捕获异常并手动执行内存访问来允许未对齐的内存访问。在 PowerPC 上,CPU 处理未对齐的整数访问,但希望操作系统处理未对齐的浮点访问。

最后,您可能会设法使用 GCC 扩展使其工作__attribute__((packed))

struct foo {
  ...
} __attribute__((packed));

这有两个效果:

  • 结构中的变量具有对齐 1(这可能会改变结构的内存布局)
  • 该结构具有对齐 1(例如,当您将其粘贴到另一个结构中时,编译器将不再对齐它)

这可能意味着 GCC 会生成执行未对齐加载所需的代码。但是你为什么要这样做呢?

于 2010-08-09T12:42:05.427 回答