memmoveで配列の中身をずらしたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
pixy

memmoveで配列の中身をずらしたい

#1

投稿記事 by pixy » 6年前

お世話になっております。
C言語で配列を使用してキューのようなものを実現しようとしていますが、想定通りに動作しないため質問致します。

本当は一般的なキューのように先頭位置と末尾位置のポインタを使用するのが良いのでしょうが、
これを実装するのも技量的に大変だと思い、単純にメモリをシフトさせる方式での実装を進めています。

今回は構造体の配列があり、データが挿入される度に配列の要素(構造体)が1つずつ後ろにずれていきます。

コード:

//構造体配列の数
#define STRUCT_MAX 10

//構造体定義
typedef struct StructData_tag {
    int id;
    int value;
} StructData;

//構造体配列の宣言
StructData struct_data[STRUCT_MAX];

//初期化
for(int i = 0; i < STRUCT_MAX; i++){
    memset(&struct_data[i], '\0', sizeof(StructData));
}

for(int j = 0; j < 100; j++){
    //データの挿入前に中身を1つ分後ろにシフトする
    //struct_data[0]~struct_data[8]をstruct_data[1]~struct_data[9]の場所にコピーする
    memmove(struct_data + sizeof(StructData), struct_data, sizeof(StructData)*(STRUCT_MAX -1));

    //配列の末尾にデータを追加
    //シフト済みなので、毎回struct_data[0]にデータを入れれば良いはず
    struct_data[0].id = j;
    struct_data[0].value = j;
}
以上のようにすることで、最終的にstruct_data[0]~[9]にfor文90~99の値が入ると想定していました。
ところが実際に動作させてみると、memmoveした時点でstruct_data[0]~[8]のデータがstruct_data[1]~[9]にコピーされず、
毎回struct_data[0]の値が上書きされるだけでした。([1]~[9]はずっと空のままです)

どう変更を加えたら想定通りの動作をするようになるのでしょうか。

nil
記事: 428
登録日時: 8年前

Re: memmoveで配列の中身をずらしたい

#2

投稿記事 by nil » 6年前

21行目の第一引数
struct_data + sizeof(StructData)
が間違っているように感じます。

http://wisdom.sakura.ne.jp/programming/c/c22.html
上のリンク先にある程度の説明があったので、細かくは省きますが、
&struct_data[1]はstruct_data+1と同値なので、これらのうちのいづれかに変更すれば動くのではないでしょうか?

printf("%p,%p,%p\n", &struct_data[1], struct_data+1, struct_data+sizeof(StructData));
を出力してみると納得できるかもしれません。

閉鎖

“C言語何でも質問掲示板” へ戻る