1

2 次元配列へのポインターに問題があります。ポインタは、可変サイズの配列を指す必要があります。

// create pointer to 2 dimensional array
TimeSlot **systemMatrix; // this is a global variable

関数で新しい配列を作成したい。

void setup(uint16_t lines, uint16_t coloumns) {
    // create 2 dimensional array. size can be set here.
    TimeSlot tmpTimeSlots[lines][coloumns];

    // make the pointer point to this array
    systemMatrix = tmpTimeSlots; // WARNING
}

しかし、ポインターが配列を指すようにすると、コンパイラーは「警告: 互換性のないポインター型からの割り当て」と表示します。さらに、別の関数から systemmatrix[2][5] にアクセスすると、ソフトウェアが実行される mikrocontroller にハード フォールトが発生します。

変数 systemMatrix は、後で tmpTimeSlots の要素にアクセスするときに必要になります。

のような組み合わせを試しました

systemMatrix = *(*tmpTimeSlot);

などがありますが、どれも機能していないようです。

どんな助けでも大歓迎です:)ありがとう!

編集: 問題が理解され、解決されました。どうもありがとうございました!

4

5 に答える 5

6

2 次元配列 != double ポインター。

これには、ほぼ確実に動的メモリ割り当てが必要です。また、配列の内容をディープ コピーする必要があります。これは非静的ローカル変数であるため、その範囲外では無効です。TYPE arr[sz]; return arr;結果としてできません。

const size_t width = 3;
const size_t height = 5;
TimeSlot tmpTimeSlot[width][height];

systemMatrix = malloc(width * sizeof systemMatrix[0]);
for (int i = 0; i < width; i++) {
    systemMatrix[i] = malloc(height * sizeof systemMatrix[i][0]);
    for (int j = 0; j < height; j++) {
        systemMatrix[i][j] = tmpTimeSlot[i][j];
    }
}
于 2012-12-19T12:35:04.750 に答える
4

あなたのsystemMatrixポインターは2D配列へのポインターではなく、二重逆参照です。次のように宣言する必要があります: TimeSlot (*systemMatrix)[columns];- これは 2D 配列ポインターの正しい型です。columnsただし、宣言 (C99 の場合) または定数 (C99 以前) の場所で値を認識する必要があります。

さらに、ローカル変数へのポインターを返すと、関数が戻った後にポインターがぶら下がります。

于 2012-12-19T12:35:07.947 に答える
2

ここにはいくつかのエラーがあります。

 TimeSlot **systemMatrix;

これは、C 多次元配列を指すために使用することはできません (後で宣言します)。代わりに、別の獣であるベクトルのベクトルを指すために使用できます(これについて詳しくは、C の本を参照してください)。ポイントは、多次元配列を指すには、次のような宣言が必要です。

 TimeSlot (* systemMatrix)[lines];

linesこれは、多次元配列のアドレス指定に使用できる長さのベクトルへのポインターです(詳細については、こちらを参照してください)。さて、これはlinesコンパイル時に知る必要があるため、あなたの場合には適切ではありません。

また、systemMatrix宣言がその関数で行う割り当てに対して正しかったとしても、その関数内で割り当てられたメモリのアドレスをそのポインターに割り当て、関数の終了後に存在しなくsystemMatrixなるため、すぐに無効なポインターになります。setupリターンとして。

ここで必要なのは、メモリの動的割り当てです。これにより、そのメモリに任意の有効期間を指定し、二重括弧構文を使用できます。

まず、必要な行数 (sizeof(int *)の呼び出しで を乗算malloc) と同じ大きさのポインターのベクトルを割り当てます。次に、行ベクトルを割り当て、それぞれを列ベクトル内のその場所に割り当てます。多次元ベクトルを動的に割り当てるためのこの (およびその他の) ソリューションの詳細については、この回答を参照してください。

free割り当てられたベクターが不要になった場合は、そのすべてを忘れないでください。

于 2012-12-19T12:46:35.327 に答える
1

2 つの問題:

  1. 自動ストレージへのポインターを返してはなりません。関数が終了すると、そのストレージは範囲外になります。代わりに malloc() を使用する必要があります。範囲外のストレージを使用すると、スタック上のジャンクにアクセスする可能性が高くなり、ハード フォールトが発生する可能性があります。技術的には、これはC では未定義の動作と呼ばれます。
  2. あなたのステートメントに反してTimeSlot **systemMatrix;、2次元配列を宣言しませんが、へのポインターへのポインターを宣言しますTimeslot。多次元配列を動的に作成する方法については、 comp.lang.c FAQを参照してください。
于 2012-12-19T12:35:33.940 に答える
1

(スタックに割り当てられた) ローカル オブジェクトへのポインターを保存し、スコープ外になった後にそれを使用しようとしています。これは間違っています。関数が完了すると、ポインターは無効になります。

また。この質問に対する回答を読んでください: Heap allocate a 2D array (not array of pointers)を参照して、2 次元配列を (スタックではなくヒープ上で) 動的に割り当てる方法を学習してください。

于 2012-12-19T12:31:55.127 に答える