コンパイラはreturn &buffer;
、 が 7 の配列uint8_t
(綴りはuint8_t (*)[7]
) へのポインターを返すことを伝えましたが、関数が を返すと言いましたがuint8_t *
、これらは異なり、互換性のないポインター型です。
と書いた場合return buffer;
、型は正しくなりますが、コードは依然として間違っています。スタック上にあるローカル配列へのポインターを安全に返すことはできません。
それを作成してstatic const uint8_t buffer[] = { … };
、関数の戻り値の型を に変更し、const uint8_t *
それに応じて使用します (データが変更されないため、スレッドセーフです)。
const uint8_t *createTestBuffer(void)
{
static const uint8_t buffer[] = { 5, 7, 3, 4, 9, 1, 3 };
return buffer;
}
または、次のような形式で動的割り当てを使用します。
uint8_t *createTestBuffer(void)
{
static const uint8_t buffer[] = { 5, 7, 3, 4, 9, 1, 3 };
uint8_t *rv = malloc(sizeof(buffer));
if (rv != 0)
memmove(rv, buffer, sizeof(buffer));
return rv;
}
ここでの呼び出しコードは、null 以外のポインターを再度取得することを確認する必要があることに注意してください。また、free()
null でない限り (呼び出しがオプションになる場合)、返されたポインターで確実に呼び出す必要があることに注意してくださいfree()
。
または、呼び出し元にバッファーを渡すようにします。ユーザーが十分なスペースを渡すことを知っていると仮定して、危険な生活を送っています。
void createTestBuffer(uint8_t *output)
{
static const uint8_t buffer[] = { 5, 7, 3, 4, 9, 1, 3 };
memmove(output, buffer, sizeof(buffer));
}
または、危険の少ない生活:
static inline size_t min(size_t a, size_t b) { return (a < b) ? a : b; }
void createTestBuffer(uint8_t *output, size_t outlen)
{
static const uint8_t buffer[] = { 5, 7, 3, 4, 9, 1, 3 };
memmove(output, buffer, min(sizeof(buffer), outlen));
}
「コピーされたバッファよりも小さい出力バッファ」を処理する方法は他にもあります。このコードは安全な範囲でコピーされましたが、切り捨てを示す 0 または 1 のステータスを返したり、指定された長さが必要な長さよりも小さくないことを表明したり、または …</p>