へたれプログラマの葛藤の日々

ザへたれPGの道

目次

Blog 利用状況

書庫

わんくま同盟

変数のどつぼへ突入

あいかわらず、VS97(VB5.0)です。(もう底なし沼で...)

そこで、一緒にやっている若いもんが、VC(ソフトはバリバリCです)で

どうしても値がまともにセットされないと行ってきたので、見てみた。

//まず、変数宣言

char  hogehoge[10];

//値をセット。(値はあくまで例題として見て下さい)

memcpy(hogehge "aaaa",sizeof("aaaa"));

ん? ん?

お前、NULLクリアしていねーじゃねーかと説教してしまいました。

すると、一言、「VBじゃいらないでしょ。」

やはり、VB6.0世代(Cなどはやっていない)方々は変数を初期値クリアすることを

しらないのだろうかと時代を感じてしまいました。

投稿日時 : 2007年2月16日 13:05

コメントを追加

# re: 変数のどつぼへ突入 2007/02/16 13:13 Hirotow

memcpyのほうがhogehgeになってますよ。

# re: 変数のどつぼへ突入 2007/02/16 13:27 とっちゃん

>NULLクリアしていねー
の前に、なぜ memcpy? strcpy じゃないの?
と小一時間問い詰めていただけるとw
一緒にやってるってことは、VB<->VCがあるんですよね?
UNICODE関係もあるはず...だったと思うww

後は、バッファサイズ関係とかも...
地雷原になりそうな...orz

# re: 変数のどつぼへ突入 2007/02/16 13:49 渋木宏明(ひどり)

strcpy でもまだアマちゃんぽ。
あと、文字列を _T() で括ってないところも×。

初期化目的なら

char hogehoge[10] = "aaaa";

でおk。

初期化と代入の区別も付かないようなら殴るw

# re: 変数のどつぼへ突入 2007/02/16 14:02 中博俊

_T()でくくるならcharじゃなくwchar_tなりTCHARなりにしないとだめっすよね?
サイズも10ってかいてあるけど、10+1ではないかとか。
strcpyも_tcscpy_sだとか・・・

# re: 変数のどつぼへ突入 2007/02/16 15:38 とっちゃん

_tcscpy_s はVS2005から。なので古ーいVCにはありません。

で、今気がついたそれよりもっと重大かつ致命的な問題が...

VS97(VC5.0)ってことは、MFC42.DLL/MSVCRT.DLL を使っているわけで...
どのランタイムがいるかもあるけど、OSがなにか?によってもあぶねーはず。
動かせるようにするのにソースに細工入れないとだめなんじゃなかったかなぁ...
#うちは、すぐに乗り換えちゃったからわからないけどw
#開発環境別建てしなきゃいけなくて苦労した記憶がw

# re: 変数のどつぼへ突入 2007/02/16 16:10 HiJun

先輩方鋭い突っ込みありがとうございます。

私自身、文字配列だったりは、領域分最初にクリアしておこう癖がついていますが、皆さんはどうですか?


補足ですが、
OS自体は、NT4.0(SP6)で統一されていますので、
UNICODE関係は問題ありません。(Win95に入れたいといわれたら、逃げます orz)
VBとVCを使っていますが、それぞれのアプリがDBのアクセスをするだけなので、タスク間通信するようなこともして
いません。

# re: 変数のどつぼへ突入 2007/02/16 16:22 中博俊

おいらがするなら
hogehoge(0) = '\0';
#w-zero3じゃ角カッコが出ねー

memsetなんてもったいない

# re: 変数のどつぼへ突入 2007/02/16 16:28 HiJun

確かに一つ目にNULL突っ込むのも手ですよね。

# re: 変数のどつぼへ突入 2007/02/16 18:36 匿名

memcpy(hogehoge,"aaaa",sizeof("aaaa"));

カンマが抜けてるのを除けば特に問題は無いですよね?

"aaaa" は \0 も付加されるので、sizeof("aaaa") は 5 を返そ
hogehoge[4] に \0 が代入されますよね?

なので、「お前、NULLクリアしていねーじゃねーか」は突っ込み所を間違ってるような・・・

なぜ char hogehoge[] = "aaaa"; じゃないのか?
なぜ "aaaa", sizeof("aaaa") なのか?

あたりを突っ込むべきかと・・・

# re: 変数のどつぼへ突入 2007/02/16 20:43 HiJun

>なぜ char hogehoge[] = "aaaa"; じゃないのか?
>なぜ "aaaa", sizeof("aaaa") なのか?
確かに、皆さんのおっしゃるとおりなので、定数の意味合いで使用しているのか確認してみたところ、

処理が
memcpy(hogehoge,cpData,sizeof(hogehoge)-1);
※引数のChar型のポインタ変数(10バイトの値+NULL止め1バイトを格納)
に変わっておりました。

担当に確認したら、hogohoge変数に値をセットして
その後の処理がまとも動くか先に確認したかったからと...
_| ̄|○

# re: 変数のどつぼへ突入 2007/02/16 21:49 2リットル

文字列リテラルにsizeof()って初めて見ました。
頭が柔らかいなー 羨ましい!

私ならhogehogeは不定値のままかな。
nullクリアでたまたま動いてしまうよりは1回目のテストでコケてくれた方が良いと考えているからです。

それにmemsetはやっぱりもったいないよね。

# re: 変数のどつぼへ突入 2007/02/16 21:59 なちゃ

NULLクリアってなんだ!?

# re: 変数のどつぼへ突入 2007/02/16 22:14 HiJun

>2リットルさんへ
確かに、テストでコケることを前提であれば、問題ないですが、
配列に格納できるサイズ内でその領域をクリアしておきたいっていうのが私の考え方です。(場合によっては、多いデータの中から特定のバイト数分取得することもありますので。)

>なちゃさんへ
2リットルさんの記述にもありますが、C言語って、
変数宣言したときの値は不定値なんです。
※VBの場合はString型の場合は""、数値型の場合は0に
なっていた気がしますが...
結局、ポインタ(メモリのアドレス)で操作することがメインである為、終端としてNULL値で判断します。
そのため、NULLクリア(変数にNULL値をセット)すれば
終端として判断できるようになるといったところですね。
NULL値をセットしていないとよくある話で、アプリケーションエラー(アドレスの参照に失敗)となることがあります。

# re: 変数のどつぼへ突入 2007/02/16 22:23 なちゃ

いやそういうこと聞いたわけでは…

char a[10];
a[0] = NULL;
とかが気持ち悪い人間のたわごとということで…

# re: 変数のどつぼへ突入 2007/02/16 22:50 中博俊

そう?気持ち悪いんだ・・・・

# re: 変数のどつぼへ突入 2007/02/16 22:51 匿名

文字列の終端は NULL ではなく '\0' ですよ。

char hogehoge[10] = {NULL};

ってすると警告でます。なので

char hogehoge[10] = {'\0'};

とするのが一般的でしょう。

ポインタの配列なら char *hogehoge[10]={NULL}; で良いですが・・・

# re: 変数のどつぼへ突入 2007/02/16 22:57 HiJun

ニュアンス違いでした。m(_ _)m

そうなると、変数をクリアするという点では
どうなんだろうといまさらながら考えさせられ
ますね。

# re: 変数のどつぼへ突入 2007/02/16 22:58 渋木宏明(ひどり)

「もったいない」以前に、文字列相手に memsetは使わないなー
配列全部0クリアはもったいない&必要性を感じないです。
通常は「文字列」相手なら ASCIIZ や std:string や CString でないと気持ち悪いです。
宣言時に初期化したい時は前述の
char hoge[10] = "aaaa";

char hoge[10] = {0};
です。
NULL を文字として扱うのも気持ち悪いですねー
NULL は無効ポインタであって、NUL 文字じゃないのにね。
NUL 文字の定義が必要なら
#define NUL 0
とすればいーのに、と思う。

# re: 変数のどつぼへ突入 2007/02/16 23:01 匿名2

0x00 or '\0' or NULL
どうなんだ?

# re: 変数のどつぼへ突入 2007/02/16 23:22 HiJun

匿名さんや渋木宏明(ひどり) さんが仰るとおり
char hoge[10] = {0};
が一般的ですね。

# re: 変数のどつぼへ突入 2007/02/16 23:37 2リットル

char hoge[10] = {0};
これってhoge[0] - hoge[9]まで0で初期化されるんじゃなかったでしたっけ?(うろ覚え;)


# re: 変数のどつぼへ突入 2007/02/17 0:26 HiJun

ちょんプロにて確認してみました。
問題なくhoge[0] - hoge[9]まで0で
初期化されております。

(自宅で、久しぶりにBorland C++を取り出してみた)

# re: 変数のどつぼへ突入 2007/02/17 0:32 えムナウ

sizeof("文字列") ってポインタに対するsizeofなので、
処理系によって2とか4とか8とか帰ってくるんじゃなかったっけ?
そこのつっこみが誰からも出ないの?

# re: 変数のどつぼへ突入 2007/02/17 0:42 匿名

全ビットが 0 のバイトは'\0'として解釈されるので
(ISO/IEC 9989:1999 5.2.1.2 を参照)
char hoge[10] = {0};



char hoge[10] = {'\0'};

は同じ意味です。

# re: 変数のどつぼへ突入 2007/02/17 0:50 匿名

文字列リテラルは char型の配列なので

sizeof("aaaa");



char buf[]="aaaa";
sizeof(buf);

と同じ事です。

ISO/IEC 9989:1999 6.7.8 を参照

# re: 変数のどつぼへ突入 2007/02/17 0:59 えムナウ

>文字列リテラルは char型の配列なので
へ~変わってたんだ。
そんな変更したなんて結構大胆だね。

# re: 変数のどつぼへ突入 2007/02/17 1:11 匿名

>ISO/IEC 9989:1999 6.7.8 を参照
訂正
ISO/IEC 9899:1999 6.5.2.5 を参照

# re: 変数のどつぼへ突入 2007/02/17 1:16 匿名

>そんな変更したなんて結構大胆だね。

変更なんてしてないかと・・・

C90 の時から文字列リテラルは char[] 型を持ちます。
(C90 については K&R 本(p.236)で確認しました。)

# re: 変数のどつぼへ突入 2007/02/17 2:40 えムナウ

C89(C90とも言われる)で決めた時にはそうなっていたんだろうね。
我々が使いだしたのはそれ以前なので規格のない時代だったのかもしれないね。
処理系での揺れがまだいっぱいあった時代ですから。

# re: 変数のどつぼへ突入 2007/02/17 12:27 HiJun

sizeof(文字列)って規格でかわっていたんですね。
(私自身がPGとしてC言語をさわりはじめたのが、
 約10年前...)

# へ~いまさらながら大胆な変更をしたもんだ 2007/02/17 13:07 えムナウ Blog

へ~いまさらながら大胆な変更をしたもんだ

# http://monclermayacheap.sinaapp.com/ 2012/10/22 11:28 モンクレール ダウンブーツ

??????????け?????????傘???????????????銈????????????伀鎰?績??????!

タイトル
名前
URL
コメント