0

4 つの行列を定義するとき、それらはメモリ内で同じ順序になると確信していましたが...

include <stdio.h>
define ROWCOUNT (3)
define COLUMNCOUNT (4)

int imat[ ROWCOUNT ][ COLUMNCOUNT ]; 
char cmat[ ROWCOUNT ][ COLUMNCOUNT ];
double dmat[ ROWCOUNT ][ COLUMNCOUNT ];
int rmat[ ROWCOUNT ][ COLUMNCOUNT ]; 

これは私が使用したコードであり、これはさまざまな行列のアドレスです: すべての行列の最初の要素を見つける

Examining imat: memory at: 1004061c0
Examining cmat: memory at: 1004062a0
Examining dmat: memory at: 100406240
Examining rmat: memory at: 100406200

私は盲目かもしれませんが、私にはそれらがirdcの順序にある​​ように見え、それは(逆であっても)定義の順序と同じではありません。なぜそれらはメモリ内で間違った順序になってしまうのでしょうか?

助けてthx :)

4

5 に答える 5

1

考えられる理由は、これらの配列のサイズが異なり (cmat は 12 バイト、dmat はおそらく 96 バイト)、コンパイラーが配置要件に合わせて配列を再配置するためです。一般的な手法は、アラインメント要件が最も厳しいオブジェクト (int、double) を最初に配置し、要件が最も少ないオブジェクト (文字配列など) を最後に配置することです。このようにして、パディングによる無駄なメモリが最小限に抑えられます。

しかし、メモリ内のさまざまなオブジェクトのシーケンスを気にするのはなぜでしょうか? 順序を強制したい場合は、それらを同じ構造体に配置します (構造体メンバーは、宣言の順序で表示される必要があります)。

于 2013-10-14T08:15:06.040 に答える
1

構造体メンバーに対して連続したメモリ割り当てが行われます。あなたの場合、配列は関数で宣言されているため、連続したメモリ位置が割り当てられる必要はありません。

コード例は次のとおりです。

#include <stdio.h>

#define ROWCOUNT 3
#define COLUMNCOUNT 4

struct test{
    int imat[ ROWCOUNT ][ COLUMNCOUNT ];
    char cmat[ ROWCOUNT ][ COLUMNCOUNT ];
    double dmat[ ROWCOUNT ][ COLUMNCOUNT ];
    int rmat[ ROWCOUNT ][ COLUMNCOUNT ];
};

int main(void)
{
   struct test obj;

    int imat[ ROWCOUNT ][ COLUMNCOUNT ];
    char cmat[ ROWCOUNT ][ COLUMNCOUNT ];
    double dmat[ ROWCOUNT ][ COLUMNCOUNT ];
    int rmat[ ROWCOUNT ][ COLUMNCOUNT ];

    printf("\n Main Arrays\n");    
    printf(" %p\n %p\n %p \n%p\n  ", (void*) imat, (void*) cmat, (void*) dmat, (void*) rmat);
    printf("\n Structure Arrays\n");
    printf(" %p\n %p\n %p\n %p\n  ", (void*) obj.imat, (void*) obj.cmat, (void*) obj.dmat, (void*) obj.rmat);
}

お役に立てれば

于 2013-10-14T08:20:09.917 に答える
0

グローバル変数の配置は、コンパイル ツールとターゲット環境によって異なります。通常は気にする必要はなく、ツールに正しいことをさせることができます。

ツールには配置を制御する機能が含まれている場合がありますが、移植性がなく、本当に必要な場合にのみ使用する必要があります。

于 2013-10-14T08:14:20.647 に答える
0

なぜそれらはメモリ内で間違った順序になってしまうのでしょうか?

どの順序が正しく、何が間違っているかをどのように定義しますか? コンパイラは、事実上すべての変数宣言を自由に再配置できます。一部の最適化をオンにすると、変数を完全にスキップすることさえできます。与えられた変数がメモリに割り当てられる順序を仮定するべきではありません。また、仮定する必要もありません。

于 2013-10-14T08:19:55.117 に答える