3

uint8_t 配列に余分なバイトを追加する obj c に奇妙な問題があります。

関連する 2 つのメソッドを次に示します。

ViewController.m

- (void)viewDidLoad {
    // hexData = NSData object
    const uint8_t *hexBytes = [hexData bytes];

    // header is first 3 bytes
    uint8_t headerBytes[] = {hexBytes[0],hexBytes[1],hexBytes[2]};

    // output the size
    NSLog(@"View did load header size: %lu", sizeof(headerBytes));

    // create a MessageHeader object
    MessageHeader *messageHeader = [[MessageHeader alloc] initWithBytes:headerBytes];
}

MessageHeader.h

- (id)initWithBytes:(uint8_t *)bytes {
    self = [super init];
    if(self != nil){
        NSLog(@"Message header init bytes size: %lu", sizeof(bytes));
        NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
        self.bytes = bytes;
    }
    return self;
}

コンソール出力

ビューはヘッダー サイズをロードしました: 3

メッセージ ヘッダーの初期バイト サイズ: 4

これは非常に奇妙です!バイトを画面に出力すると、明らかな理由もなく余分なバイトがデータに追加されたことが示されます。eef231が入力の場合はeef23150、init メソッドの出力です。その余分なバイトは一見ランダムです。

メソッドuint8_t headerBytes[]uint8_t *bytesの間のキャストではないかと思います。init

誰かがそれについてさらに情報を持っているなら、それは素晴らしいことです。ありがとう

4

3 に答える 3

4

sizeofコンパイル時の演算子であり、あなたが思っていることをしません。

uint8_t[] の sizeof は、その配列のサイズを示します。これは、1 バイト * 3 要素 = 3 バイトです。これができるのは、配列宣言に暗黙的なサイズ情報が添付されているためです。

uint8_t* の sizeof は、ポインターのサイズを示します。これは、32 ビット システムでは 4 バイトです。

それが何をするかについての良いアイデアについては、ウィキペディアの記事を参照してください。sizeof

配列の長さを渡したい場合、一般的な規則は、追加の長さパラメーターを渡すことです。目的の c で作業しているため、データの配列とそのサイズを含むことができる NSData を渡す必要があります。

于 2013-01-17T09:34:02.320 に答える
1

問題は次のinitWithBytes:とおりsizeof(bytes)です。ポインター変数のサイズがわかり、32 ビット アーキテクチャでは 4 バイトになります。

呼び出された関数で元の C 配列のサイズを取得する方法はありません (実行時に C 配列はサイズ情報を保持しません)。追加の引数としてサイズを渡す必要があります。

于 2013-01-17T09:32:18.303 に答える
1

bytesuint8_t *はin initWithBytes、つまり へのポインタとして宣言されていますuint_t

ハードウェアの場合、ポインタのサイズは4 バイトです。そのメソッド内では不明な配列サイズとは関係ありません。

于 2013-01-17T09:30:00.983 に答える