掲示板利用宣言

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

 私は

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

掲示板2

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

No.26363

バッファの挙動について
投稿者---RingBuffer(2006/03/09 15:52:10)


ややこしいことで困っています。
知っている方は即座にわかることでしょうが、
以下の関数の挙動で理解できないことがあります。
御知恵をお貸し下さい。
void file_write_test(char* pw, char* inbuf, int count)
{
    char outbf[count];
    char pwbuf[16];

    memset(pwbuf, 0x20, sizeof(pwbuf));
    strncpy(pwbuf,pw,16);
    if (efp == NULL) {
        if((efp = fopen("/var/test1.test", "a")) == NULL ) {
            printf("ファイルオープンエラー\n");
            exit(1);
        }
    }
    if (efp1 == NULL) {
        if((efp1 = fopen("/var/test2.test", "a")) == NULL ) {
            printf("ファイルオープンエラー\n");
            exit(1);
        }
    }
    fwrite(pwbuf, sizeof(char),16,efp);
    fprintf(efp1,"%s\n", pw);
}



という関数を外部から100回ほど呼ぶ必要があるプログラムを作成中です。
そのとき、
/var/test1.testの出力が
abcdefgdefggcdefgfgbcdefgefgdefggcdefgfgbcdefgefgdefggcdefgfgbcdef...
となり
/var/test2.testの出力が
abcdefg
abcdefg
abcdefg
abcdefg
abcdefg
...
となります。
\nを入れているのでtest2.testの出力は良いのですが
test1.testの出力が期待したものになりません。
何がまずいのでしょうか?


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:バッファの挙動について 26364 Blue 2006/03/09 16:06:22
<子記事> Re:バッファの挙動について 26369 ぽへぇ 2006/03/09 21:00:59
<子記事> Re:バッファの挙動について 26370 shu 2006/03/09 21:07:44


No.26364

Re:バッファの挙動について
投稿者---Blue(2006/03/09 16:06:22)


  1. どのような結果が期待したものなのか?
  2. 入力はなんなのか?
  3. 開発環境はなんなのか?

をまず、解答してください。


とりあえず、strncpyは
strncpyについてにもあったように、
const char* text = "abc";
char buff[ 10 ];

memset( buff, 0x20, sizeof( buff ) );
strncpy( buff, text, sizeof( buff ) );

とすると、abc以降の文字が全て'\0'になります。(半角空白は全部なくなる)


この投稿にコメントする

削除パスワード

No.26365

Re:バッファの挙動について
投稿者---RingBuffer(2006/03/09 16:46:43)


>
  1. どのような結果が期待したものなのか?
  2. 入力はなんなのか?
  3. 開発環境はなんなのか?


失礼致しました。Fedora 4 gcc-4.2 での開発中のシステムです。
問題としたファイルですがバイナリエディタで見たらきちんと入っていました。
od でもmoreでもある程度見えたので、
変な情報に化けたのかと思ってしまったわけです。
C++からCを呼び出す関数で、Cの方にバッファの内容と暗号化キーを渡し
暗号化し、ファイルに書き込むという処理で
C単体ではファイル読みだし、暗号化ツールおよび、復号化ツールの動作は
出来ています。
そのときC++から操作し、Cの暗号化関数に渡して
暗号化ファイル作成後に
Cで作成したツールでの復号化でまったく意味のない情報に化けてしまいました。
(先に示したファイルはC++からC関数に渡された生データの
テキスト出力です。)
そこでバッファリングを疑ったわけですが、しかし、
バッファリングはうまく動作して
いるようなので別の問題のようです。
コンパイラの違いか、その他なのでしょう。
もう少し調査が必要なようです。


この投稿にコメントする

削除パスワード

No.26366

Re:バッファの挙動について
投稿者---RingBuffer(2006/03/09 18:23:01)


>コンパイラの違いか、その他なのでしょう。
>もう少し調査が必要なようです。

自己解決したのですが、嫌になりますね。
メモリもクリアして、暗号キーを書き込んだのですが、
C++のコンパイラの方は奇数バイトのとき
例えば,"abc"の場合
0x62 0x61 0x00 0x03
となり
Cコンパイラでは
0x61 0x62 0x63 0x00
となっていました。
これでは暗号ファイルを解読は出来ませんね。
双方ともg++、gccに変えるか、Cの方でバッファ変換機能を
つけないといけませんね。
大きなソースだから嫌だなあ。


この投稿にコメントする

削除パスワード

No.26367

Re:バッファの挙動について
投稿者---nop(2006/03/09 20:14:01)


どこかで変な処理をしていると思われ。

# 情報が少なすぎて何とも言えないが…
# エンディアン問題の未考慮があるなど。


この投稿にコメントする

削除パスワード

No.26368

Re:バッファの挙動について
投稿者---RingBuffer(2006/03/09 20:39:39)


>どこかで変な処理をしていると思われ。
>
># 情報が少なすぎて何とも言えないが…
># エンディアン問題の未考慮があるなど。
その可能性は十分あります。
rijndaelでストリーミング暗号録画再生機能を作ることが
1週間で与えられた課題でして、ばたばたで作りましたので、
まったく考慮不足は否めません。
rijndaelはブロック暗号化方式なんですが、1単位が16バイトと
小さいため、DVD再生くらいには不自由せずに使えます。
しかし、巨大システムの一部の改造のため
リトルエンディアン、ビッグエンディアンのどちらを使っているか
なんて追っかけることもせずにつくり出したことは大きな問題ですね。
それでも、皆様の御尽力とバイナリエディタのおかげでなんとか
1日の遅れで処理が出来るようになりました。

また困ったら御知恵を借りに参ります。


この投稿にコメントする

削除パスワード

No.26369

Re:バッファの挙動について
投稿者---ぽへぇ(2006/03/09 21:00:59)


> fwrite(pwbuf, sizeof(char),16,efp);
pwbufの中がどうあれ問答無用で16文字書かれる。

>fprintf(efp1,"%s\n", pw);
pw の中に\0があればそこで出力が終わる。
の違いでは?

コンパイラやバッファの違い云々以前の問題のような気がします。



この投稿にコメントする

削除パスワード

No.26370

Re:バッファの挙動について
投稿者---shu(2006/03/09 21:07:44)


100回繰り返す関数にしては、複雑過ぎる。
標準関数を真似て(単機能、名前のつけ方、型や引き数など)、
1つの関数は極々限られた機能にした方が良い。

繰り返し処理のなかで、肝心の書きこみ処理の部分(fprintf, fwrite)は、既に標準関数として存在しているので、

for (i = 0; i < 100; i++)
    fprintf(/* 省略 */);
	
for (i = 0; i < 100; i++)
    fwrite(/* 省略 */);

などと、繰り返してやれば良い。

file_write_test()という関数は、作らなくても良いかもしれない。


↓のようの細かいプログラムを作って確認してみる。

main()のみ(関数化しないで)、test1.testファイルに書きこみたい内容を、
画面に表示(ファイル出力無しで標準出力)するプログラム。

main()のみ、(関数化しないで)、test2.testファイルに書きこみたい内容を、
画面に表示(ファイル出力なしで標準出力)するプログラム。


この投稿にコメントする

削除パスワード

No.26371

Re:バッファの挙動について
投稿者---RingBuffer(2006/03/10 09:19:34)


>100回繰り返す関数にしては、複雑過ぎる。
>標準関数を真似て(単機能、名前のつけ方、型や引き数など)、
>1つの関数は極々限られた機能にした方が良い。

100回繰り返すとはソースを単純化するために、
そのような言葉回しを使用しました。
処理としては、2時間程度の画像録画処理に
rijndaelで暗号化する機能を付け加え、
同時に復号化ストリーミング再生を実現するものです。
rijndaelと録画再生機能のインタフェースを作成することが
要求されたもので、録画再生機能のどこに手をつければ良いのか
の調査もそこそこに開発を始めたということもあると思います。

まあよくわかっていないというのもひとつありまして、
デバイス標準入力の接続、DBとのやりとりを行いながら
ファイル名や、録画時間等を決めポーリングプロセスを立ち上げそこに
必要情報を送るというプロセスと、ポーリングプロセス(名前が変かも)において
デバイス入力からの読み込み、MP3で圧縮化しリングバッファーに書き込み、
リングバッファーを返してやり、そこでファイル化する
という一連の流れの中からどこに暗号化/復号化を入れればよいかという
ことでエイヤと決めた点も問題かも知れません。

実際はファイル化する直前に暗号化したかったのですが
リングバッファからファイル化するポーリングプロセスの
実態を調査し切れず、比較的探しやすかったMP3圧縮化の直後に
暗号化処理を入れたことがあるのかも知れません。
ただし、処理は画像劣化もなく動いているので、
これ以上追っかけることは本処理ではないと思います。
(バグやユーザ要求追加による変更は多分にありますが)

どうもお騒がせ致しました。


この投稿にコメントする

削除パスワード

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