掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.27797

連続した変数の内容を取得する方法
投稿者---TAKE(2006/08/01 21:14:21)



TAKEです。よく拝見させて頂いております。

良い方法が思いつかない為、質問させていただきました。

int a,b;
char b;
short c;



int z;

上記のように、様々な型の変数が存在するとします。
上記変数群a〜zは連続したアドレスにあることが保障されています。

aからzまでの全内容のダンプを取る必要が出てきた為、
開始アドレス(aのアドレス)と終了アドレス(zのアドレス)を取得し、
ポインタを進めて1BYTEずつchar型配列に格納する方法を取ろうと考えています。

ただ、これをどのように実現すれば良いのかで詰まっております。
以下のコードは試しに作ったものですが、これはダメです。。。
で、正常に動かす方法がどうもうまく思いつきません。

この手法を実現する方法がございましたら、ご教授願えませんでしょうか?
このダンプの取り方自体がまずいのでしょうか?

動作確認で使用している環境
-------------------------
OS : Win XP
コンパイラ : cygwin gcc
-------------------------
(実機は独自のコンパイラを使用しております。こちらの環境で、
アドレスが連続していることは保障されています。)

どうぞ、よろしくお願い申し上げます。


/* これは動きませんが、一応。。。
こんな感じで作れないかと考えたものです */
#include<stdio.h>

int main(void)
{
    int a,b,c;
    short d;
    char e;

    int i;

    int *st,*end;
    char dump[20]; // 動作確認用なので適用に確保してます。

    a=b=c=d=e=1;

    printf("%p\n%p\n%p\n%p\n%p\n",
            &a,&b,&c,&d,&e);     // 一応アドレス確認

    st = &e;
    end = &a;

    while(st < end){
        dump[i] = *st;
        st++;
        i++;
    }

    return 0;
}





この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:連続した変数の内容を取得する方法 27798 επιστημη 2006/08/01 21:28:10
<子記事> Re:連続した変数の内容を取得する方法 27799 RiSK 2006/08/01 21:45:41
<子記事> Re:連続した変数の内容を取得する方法 27800 たかぎ 2006/08/01 21:51:48
<子記事> Re:連続した変数の内容を取得する方法 27806 shu 2006/08/02 00:12:34
<子記事> Re:正常動作を確認できました 27818 TAKE 2006/08/03 21:36:03


No.27798

Re:連続した変数の内容を取得する方法
投稿者---επιστημη(2006/08/01 21:28:10)


> int *st,*end;

char *st, *end;
ぢゃなくて?



この投稿にコメントする

削除パスワード

No.27799

Re:連続した変数の内容を取得する方法
投稿者---RiSK(2006/08/01 21:45:41)


union を使ってみるのはいかが?


この投稿にコメントする

削除パスワード

No.27800

Re:連続した変数の内容を取得する方法
投稿者---たかぎ(2006/08/01 21:51:48)
http://takagi.in/


こんな感じかな?

#include <stdio.h>
#include <string.h>

int main(void)
{
    int a, b, c;
    short d;
    char e;

    int i = 0;

    const char *st,*end;
    char dump[20];

    a=b=c=d=e=1;

    printf("%p\n%p\n%p\n%p\n%p\n",
            &a,&b,&c,&d,&e);     // 一応アドレス確認

    st = (const char*)&e;
    end = (const char*)&a + sizeof(a);

    while(st < end){
        dump[i] = *st;
        st++;
        i++;
    }

    return 0;
}

今回はたまたま動きますが、境界調整とか変数の配置とか、十分気をつけてください。



この投稿にコメントする

削除パスワード

No.27802

Re:連続した変数の内容を取得する方法
投稿者---Hermit(2006/08/01 22:08:49)


>printf("%p\n%p\n%p\n%p\n%p\n",&a,&b,&c,&d,&e); // 一応アドレス確認
が無い時、最適化によって、レジスタに取られるため、メモリ上に無い場合も。

>a=b=c=d=e=1;
が無いなら、変数自体が消えてなくなる時もあります。


この投稿にコメントする

削除パスワード

No.27803

Re:連続した変数の内容を取得する方法
投稿者---TAKE(2006/08/01 22:59:21)


返信、ありがとうございます。
助かります。

#επιστημη様
charの間違いです。。。ご指摘ありがとうございます。

#RiSK様
私unionの利用に慣れておらず、、
unionを使っての実現方法がイメージできません。
よろしければ教えて頂けますでしょうか?

#たかぎ様
サンプルありがとうございます。
型を合わせてやる必要があった訳ですね。
最後の変数のサイズを取るのも忘れてました。。
あと、境界調整の箇所がないか等、再度確認しておきます。
ありがとうございます。

#Hermit様
そうなんですか。。
実際のコードは全てに何らかの処理がある為、
恐らくその辺の所は大丈夫と思われますが、確認してみます。
ありがとうございます。

皆様のご意見を元に、再度確認してみたいと思います。
また確認後報告させて頂きます。(書き込めるのが明日の晩になりますが)
ありがとうございました!



この投稿にコメントする

削除パスワード

No.27808

Re:連続した変数の内容を取得する方法
投稿者---円零(2006/08/02 22:32:45)


今日は来ないかな?

試しに作ってみた、可変個引数に対応した例。

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>

#define var(v) sizeof v, &v

struct BUF{
    unsigned char *byte;
    int length;
};

struct BUF *dump(struct BUF *dmp, int num, ...){
    char *head, *tail;
    unsigned char *v;
    int i, j, varsize, tailsize;
    va_list ptr;

    va_start(ptr, num);
    tailsize = va_arg(ptr, int);
    head = tail = va_arg(ptr, char*);
    for(i = 1; i < num; i++){
        varsize = va_arg(ptr, int);
        v = va_arg(ptr, unsigned char*);
        if(v < head) head = v;
        else if(v > tail){
            tail = v;
            tailsize = varsize;
        }
    }
    dmp->length = tail + tailsize - head;
    if( (dmp->byte = calloc(dmp->length, 1))== NULL ) exit(1);
    va_start(ptr, num);
    for(i = 0; i < num; i++){
        varsize = va_arg(ptr, int);
        v = va_arg(ptr, unsigned char*);
        memcpy(dmp->byte + (v - head), v, varsize);
    }
    va_end(ptr);
    return dmp;
}

int main(void){
    int a, b ,c;
    short d;
    char e;

    int i;
    struct BUF dmp;

    a=b=c=d=e=1;
    printf("%p\n%p\n%p\n%p\n%p\n",
            &a,&b,&c,&d,&e);     // 一応アドレス確認

    dump(&dmp, 5, var(a), var(b), var(c), var(d), var(e));
    for(i = 0; i < dmp.length; i++) printf("%02x ", dmp.byte[i]);
    return 0;
}



この投稿にコメントする

削除パスワード

No.27804

Re:連続した変数の内容を取得する方法
投稿者---たかぎ(2006/08/01 23:36:47)
http://takagi.in/


>>printf("%p\n%p\n%p\n%p\n%p\n",&a,&b,&c,&d,&e); // 一応アドレス確認
>が無い時、最適化によって、レジスタに取られるため、メモリ上に無い場合も。
>
>>a=b=c=d=e=1;
>が無いなら、変数自体が消えてなくなる時もあります。

この辺の問題をクリアするには、変数をvolatile修飾しておくのが吉ですね。



この投稿にコメントする

削除パスワード

No.27805

Re:連続した変数の内容を取得する方法
投稿者---Hermit(2006/08/02 00:03:48)


見落としてましたが、
>(実機は独自のコンパイラを使用しております。こちらの環境で、アドレスが連続していることは保障されています。)

とあるので、問題ないかも(^^;




この投稿にコメントする

削除パスワード

No.27806

Re:連続した変数の内容を取得する方法
投稿者---shu(2006/08/02 00:12:34)


//
//	こういうことがしたいのだろうか?
//

//
#include <stdio.h>

//////////////
int main(void)
{
    struct dump {
        int a, b, c;
        short d;
        char e;
    } data;
    const char *p;
    int i;
    
    //
    p = (const char *) &data;
    data.a = data.b = data.c = data.d = data.e = 1;
    
    printf("%p\n%p\n%p\n%p\n%p\n",
        &data.a, &data.b, &data.c, &data.d, &data.e);
    
    for (i = 0; i < sizeof(struct dump); i++) {
        printf("%02x ", p[i]);
    }
    
    return 0;
}



この投稿にコメントする

削除パスワード

No.27818

Re:正常動作を確認できました
投稿者---TAKE(2006/08/03 21:36:03)


皆様コメントありがとうございました。(昨日は書き込み出来ませんでした。。)

修正したコードは載せることは出来ないのですが、初めに考えた方法を
そのまま使用し、型が合っていなかった部分を対応して、警告を出さず正常動作することを
確認できました。

↓↓この部分
st = &e; → st = (const char*)&e;
end = &a; → end = (const char*)&a + sizeof(a);

#shu様、円零様
ご返信ありがとうございます。
動作確認用に適当に変数を宣言したコードでここに書き込みさせて頂きましたが、
実際のコードは大きな変更は出来ないです。。。既存コードからの追加なので。

変数は既にあるものなので構造体でくくれないですし、ダンプ処理を入れるモジュールは
決まっていて、この処理の間にダンプを取るってな感じなので、
あまり大きな処理は入れられないです。なので初めに考えた案を使用しました。
提示して頂いたコードは、個人的に勉強用に参考にさせて頂きたいと思います。
ありがとうございました。

この掲示板でしばしば勉強させてもらっているのですが(人の質問のやり取りを
見ていると非常に勉強になります)、
今後も参考にしながら活用させていただこうと思います。

またどうしようもなくなったら書き込みさせてもらう事があるかも知れませんが、
よろしくお願い致します。

コメントを下さった皆様、本当に助かりました。
ありがとうございました。





この投稿にコメントする

削除パスワード

No.27844

Re:正常動作を確認できました
投稿者---shu(2006/08/04 13:58:19)


>↓↓この部分
>st = &e; → st = (const char*)&e;
>end = &a; → end = (const char*)&a + sizeof(a);

endの宣言をaの宣言の前にもってきて、
    end = (const char*)&end;

でもよいのかも。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧