3

次のような動的配列を作成しました。

#include <stdlib.h>

typedef struct {
    size_t capacity;
    size_t len;
} __dynarray_header;

void* dynarray_new() {
    __dynarray_header* header = malloc(sizeof(__dynarray_header));
    header->capacity = 0;
    header->len = 0;
    return header + 1;
}

動的配列は操作でアクセスできます[]。サイズを変更するときは、__dynarray_header*)array - 1容量と長さの情報を取得するために使用できます。

このアイデアは小さなテストで機能します。ただし、GCC は、strict-aliasing を壊すことについて警告します。

-fno-strict-aliasingまた、コンパイラ オプションなしで (-O3最適化ありで)いくつかの大規模なプロジェクトの segfault も見つかりました。

strict-aliasing とは何か、私のコードが strict-aliasing を破る理由を知っています。

[]私の質問は次のとおりです。操作と動的サイズ変更の両方をサポートする動的配列を実装するより良い方法はありますか?

追加:

この動的配列を使用したデモ プログラム:

int* arr = dynarray_new();
arr = dynarray_resize(sizeof(int) * 2);
arr[0] = 1;
arr[1] = 2;
arr = dynarray_resize(sizeof(int) * 4);
arr[2] = 3;
arr[3] = 4;
dynarray_free(arr);
4

2 に答える 2

1

すでに述べたように、C 標準がそのようなことを予見している手法は柔軟な配列です。

typedef struct {
    size_t capacity;
    size_t len;
    unsigned char data[];
} dynarray_header;

structこのようなを十分なスペースで割り当てる (または再割り当てする)と、配列のdataように要素にアクセスできますunsigned charchar型は他のデータ型をエイリアスする可能性があるため、問題はありません。

コンパイラが柔軟な配列をサポートしていない場合は[1]、そこにa を入れてdataください。

ところで、アンダースコアで始まる名前はファイル スコープで予約されているため、これらを使用することは想定されていません。

于 2013-07-02T05:21:41.253 に答える