2017-10-31 13 views
-2

固定長文字列の可変長配列を使用して構造体を作成しようとしています。今割り当てられた2D配列に書き込む

struct foo_query{ 
    char tag[10]; 
    int value_count; 
    char * values[VAL_SIZE]; 
}; 

、私はこれらの構造体の配列を作成し、値のためにいくつかのメモリを割り当てたい:

#define buffer(a) (char *) malloc(sizeof(char[a][VAL_SIZE])) 
foo_query queries[total_queries] = { 
    {"FOO", 25, buffer(25)}, 
    {"BAR", 21, buffer(21)} 
}; 
#undef buffer 

は最後に、私は実際の値にいくつかのデータを書きたいです。

query_index = 0; 
for(int i = 0; i < queries.value_count; i++){ 
    strncpy(queries[query_index].values[i], "Hello", VAL_SIZE); 
    Serial.outln("success"); 
} 

しかし、最後のビットは失敗します。 successが1回または2回印刷され、すべてが停止します。

私の知る限りでは、メモリは割り当てられていますが、何もあふれているわけではないので、なぜコードがクラッシュするのですか?

+0

[この1つ]のような質問がありました。(https://stackoverflow.com/questions/12462615/how-do-i-correctly-set-up-access-and-free-a-multidimensional -array-in-c?noredirect = 1&lq = 1)、しかし、私はそれがその質問に対して何を言っているのか、私のコードはまだ動作しません。 –

+0

'strncpy'は文字列がNULで終了することを保証しません –

+0

この場合、なぜそれが関連するのか分かりません。問題は、書き込みではなく、読み込みで発生しています(実際には配列から読み取ることはありません)ので、NULL終了によって違いはありません。 –

答えて

0

あなたのメモリ割り当ては基本的に間違っています。

foo_query queries[total_queries] = { 
    {"FOO", 25, buffer(25)}, 
    {"BAR", 21, buffer(21)} 
}; 

あなたは方法は、あなたがそれを定義したため、上記の、あなただけのvaluesの最初の要素を移植しているqueriesを作成

valueschar *の配列です。

iが0より大きい場合、その配列に値を入れると、割り当てられていないポインタにコピーされます。

strncpy(queries[query_index].values[i], "Hello", VAL_SIZE); 

iが0より大きい、queries[query_index].values[i]がNULLであり得るか、またはそれがメモリの一部を指すことができます。いずれにしても、定義されていない動作とコードがランダムにクラッシュすることになります。

VAL_SIZE文字をコピーしようとすると、実際にはvaluesが間違って定義されている可能性が高くなります。 char *の配列ではなく、charの配列VAL_SIZEへのポインタを探している可能性は高いですか?またmalloc(sizeof(char[VAL_SIZE})*(a))としてより明確になり、あなたがmallocに割り当てているメモリの奇妙量に収まるように

char (* values)[VAL_SIZE]; 

:その場合は、あなたはとしてそれを定義する必要があります。 (注:ブラケットでマクロパラメータをラップすると、曖昧な優先順位の問題が発生しないようになります。つまり、buffer(10+10)は、malloc(sizeof(char[VAL_SIZE})*10+10)になります)。

あなたはまだstrncpy

queries[query_index].values[i][VAL_SIZE-1]='\0'; 

はちょうどあなたの文字列がNULがあまりにも終了していることを、文字列がコピーされている場合は、中に収まるように大きすぎることを確認するには追加する必要があります。

関連する問題