2

consider the following Objective-C++ iPhone Application (TestMemAppDelegate.mm). It crashes with an EXC_BAD_ACCESS on the iPhone (3GS with iOS 4.0). It works fine in the Simulator. It is clearly a memory alignment thing, because it works fine on the iPhone if the "DataA" struct starts on a 8 Byte border.

Can anyone explain the cause? Is it something with the ARM architecture? ARM compiler?

@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;

ただし、アラインメント要件があるため、ポインターを任意に変更しても動作することは保証されません。

とはいえ、OS は、例外をキャッチしてメモリ アクセスを手動で実行することにより、ミスアライメント メモリ アクセスを許可できます。PowerPC では、CPU は位置合わせされていない整数アクセスを処理しますが、OS は位置合わせされていない浮動小数点アクセスを処理することを期待しています。

最後に、GCC 拡張機能を使用して動作させること__attribute__((packed))できます。

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

これには 2 つの効果があります。

  • 構造体の変数の配置は 1 です (これにより、構造体のメモリ レイアウトが変更される場合があります)。
  • 構造体のアラインメントは 1 です (たとえば、別の構造体に貼り付けた場合、コンパイラはそれをアラインしなくなります)。

これは、GCC がミスアライメント ロードを実行するために必要なコードを生成することを意味している可能性があります。しかし、なぜこれをしたいのですか?

于 2010-08-09T12:42:05.427 に答える