C言語なら俺に聞け! Part 114
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん
2005/09/17(土) 00:26:58質問する前には最低限検索を。
GUIなどの標準Cではできない事の質問は使用している開発環境のスレへGo! (←ここ注目)
ソース丸投げ、宿題、書籍 は専門の別スレがあるのでそこへさようなら。
エラー(警告含む)が起きたのならばエラーメッセージを書きましょう。
C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/
Cプログラマ必読 ・プログラミング言語C(通称 K&R)
http://www.amazon.co.jp/exec/obidos/ASIN/4320026926/
C言語なら俺に聞け! Part 113
http://pc8.2ch.net/test/read.cgi/tech/1125136478/
他の過去ログはここに
http://nssearch.hp.infoseek.co.jp/clang/
0232デフォルトの名無しさん
2005/09/19(月) 01:28:290233デフォルトの名無しさん
2005/09/19(月) 01:30:05ケースバイケースです。以上。
0234デフォルトの名無しさん
2005/09/19(月) 01:30:47普通は
・確保したバッファを呼び出し元の関数に返したい場合
・途中でバッファのサイズを拡張する可能性がある場合
・サイズが128ではなくてデカ過ぎる場合
はmallocを使う。それ以外なら上で良いでしょう。
0235デフォルトの名無しさん
2005/09/19(月) 01:48:56デバッグ用にprintfっぽく使えるメッセージボックスを作ろうと思ったんですが・・・
しょっちゅう呼び出す関数は確保→開放ってやると遅くなるかと思って・・・
>>234
ありがとうございます。
0236デフォルトの名無しさん
2005/09/19(月) 02:05:02デバッグでパフォーマンスは気にしない。
0237デフォルトの名無しさん
2005/09/19(月) 02:29:41メッセージボックスの表示のオーバーヘッドで
全く気にならないはずだ。
0238デフォルトの名無しさん
2005/09/19(月) 02:31:56メモリを保持してないポインタはNULLにしておくべきだろ
アロケート目的に使わないならfreeしないから関係ないけど。
>、「0フィルしておけば安全」という間違った考えがバグを生みデバッグを困難にする
それはどんな状況ですか?
そういう経験はしたことないんですけど。
0239デフォルトの名無しさん
2005/09/19(月) 02:59:03○NULL フィルしておけば、NULL フィルしないよりは安全
NULL フィルしたからといってバグがなくなるわけではないが、バグ検出に役に立つ。
NULL へのアクセスは大抵の環境で実行時エラーが出る。
NULL フィルしなかった場合は、偶然どこかの正常なアドレスを指してる可能性がある。
例えば、昔ポインタとして使われたスタック領域と同じところに
そのポインタが割り当てられたときなどは、可能性としては十分あり得る。
代入が直後にある場合などは必要ないと思うかもしれないし、
実際入れなくても現時点では何も問題はないが、
後の拡張やコードの移動により問題が発生する可能性はある。
NULL フィルのオーバーヘッドが気になるような状況でもない限り、
NULL フィルしといた方が安全ってのは正しい。
0240デフォルトの名無しさん
2005/09/19(月) 03:07:090241デフォルトの名無しさん
2005/09/19(月) 03:12:140242デフォルトの名無しさん
2005/09/19(月) 04:01:36詳しく
0243デフォルトの名無しさん
2005/09/19(月) 04:23:47それは紛らわしい書き方なんだが、
かといって正確に書こうとするとややこしい。
>>242
http://www.kouno.jp/home/c_faq/c5.html#0
0244デフォルトの名無しさん
2005/09/19(月) 04:54:06それはコンパイラに依存すると言うことですよね?
いちいちコンパイラの仕様を確認しなければならず、
違っていればやり方を変えなければならないと言うことですよね?
デバッグビルドとリリースビルドで動作が違ってくるって事ですよね?
デバッグビルドで取り除けるバグを、リリースビルドで見つけなければならないと言うことで、
デバッグが大変になりますよね?
0245デフォルトの名無しさん
2005/09/19(月) 04:57:230246デフォルトの名無しさん
2005/09/19(月) 05:07:280247デフォルトの名無しさん
2005/09/19(月) 05:09:44自分の主張と、間違ってると思われる発言を書けよ
自分のアホは指摘されたくないってか?
0248デフォルトの名無しさん
2005/09/19(月) 05:20:59もしかしてコンパイラに固定値突っ込ませてデバッグ後、
固定値突っ込むのをOFFにするオプションつけたデバッグビルドでもデバッグするのかな?
少しでもコードを取り除きたいならそれもいいかもね。
めんどくさ。
0249デフォルトの名無しさん
2005/09/19(月) 05:22:12ねーよwwwwwwwwwwww
0250デフォルトの名無しさん
2005/09/19(月) 05:25:000251デフォルトの名無しさん
2005/09/19(月) 05:33:59間違って上書きしちゃったどうしようdocだけ最インストできそうだけど
manはどうしようってなってる俺をどうにかしてみろよおめーら
0252251
2005/09/19(月) 05:36:21激しく誤爆しちまったじゃねえか
ついでにすれ違い覚悟で聞いてみるけど
どうしたら一番効率よくもどにもどせれる?
0253デフォルトの名無しさん
2005/09/19(月) 05:36:34VC5のコンパイラのバグでlongdoubleの演算最適化ができなかった。
リリースビルドでしか再現しなかった。
MSにコード渡してチェックしてもらったけど、コーディングの問題はないと言われた。
プラグマでその部分の最適化を外して対応した。
>>250
実務未経験プログラマから見れば必死に見えるのか。
0254デフォルトの名無しさん
2005/09/19(月) 05:40:57コピー元ファイル一覧をつくり、
delコマンドのバッチファイルにし、実行する。
0255デフォルトの名無しさん
2005/09/19(月) 05:49:50DOSでもいいけど
ファイル一覧をパイプでdelコマンドに渡すのが一番早いかな。
でも僕は使い慣れてないからテストしてからじゃないと実行しない。
テストするならバッチに書いたほうが確実で早いと。
VZエディタからのキーボードマクロにはお世話になった。
0256デフォルトの名無しさん
2005/09/19(月) 10:11:110257デフォルトの名無しさん
2005/09/19(月) 11:16:07ヘキサかよw
0258デフォルトの名無しさん
2005/09/19(月) 11:44:07ttp://aferieito.gozaru.jp/
0259デフォルトの名無しさん
2005/09/19(月) 11:50:560260デフォルトの名無しさん
2005/09/19(月) 11:56:050261デフォルトの名無しさん
2005/09/19(月) 13:44:52私は一回ありましたよ。
詳細は忘れてしまいましたが法線を求めた時にデバッグビルドだと0、
リリースビルドだとINFになりました。
数学関数の挙動に違いがあったとかそんな感じです。
0262デフォルトの名無しさん
2005/09/19(月) 14:02:44メモリリークを調べるため、
自作のアロケーターでmalloc関数群を隠そうと思います。
void *chk_malloc(size_t size, file, line) {
}
#define malloc(size) chk_malloc(size, __FILE__,__LINE__)
こんな感じです。
この場合、
int (*f)() = malloc;
の様に値として代入が発生した場合は関数マクロは効力が発揮できませんが、
この場合でもchk_mallocを代入するように細工する方法はないでしょうか。
#define malloc chk_malloc
とすると fileとlineの情報が欠落してしまいます。
0263デフォルトの名無しさん
2005/09/19(月) 14:16:24グローバル変数へパラメータを追い出してみるのはどうだろう
const char*chk_malloc_file;int chk_malloc_line;
void* chk_malloc_(size_t sz){
}
void*(*chk_malloc(const char*file,int line))(size_t){
chk_malloc_file = file;chk_malloc_line = line;
return chk_malloc_;
}
#define malloc chk_malloc(__FILE__,__LINE__)
まぁこの実装だと同時に2箇所以上で使うと破綻するけど
0264デフォルトの名無しさん
2005/09/19(月) 14:17:13ありがとうございます。
面白いですね。
試してみます。
0265デフォルトの名無しさん
2005/09/19(月) 14:21:11そりゃ、関数ポインタ自体に file と line 用の引数がない限り、どうしようもないわな。
#ifdef NDEBUG
typedef void* (*malloc_fp_t)(size_t size);
#define MALLOC_FP malloc
#define MALLOC_CALL(fp, size) fp(size)
#else
void* chk_malloc(size_t size, const char* file, int line);
typedef void* (*malloc_fp_t)(size_t size, const char* file, int line);
#define MALLOC_FP chk_malloc
#define MALLOC_CALL(fp, size) fp(size, __FILE__, __LINE__)
#define malloc(size) chk_malloc(size, __FILE__, __LINE)
#endif
malloc_fp_t fp = MALLOC_FP;
char* buf = MALLOC_CALL(fp, size);
こんなところだと思うが・・・。
0266263
2005/09/19(月) 14:21:22const char*chk_malloc_file;int chk_malloc_line;
void* chk_malloc(size_t sz){
return malloc(sz);
}
#define malloc (chk_malloc_file = __FILE__ , chk_malloc_line = __LINE__ , chk_malloc)
0267デフォルトの名無しさん
2005/09/19(月) 14:24:24それだと、関数ポインタを使ったとき(メモリを確保したとき)の情報じゃなくて、
関数ポインタに代入したときの情報が表示されてしまうと思うのだが。
発想の面白さは買うけど。
0268デフォルトの名無しさん
2005/09/19(月) 14:28:37大変勉強になります。
ありがとうございます。
0269デフォルトの名無しさん
2005/09/19(月) 14:32:10#define MALLOC_CALL(fp, size) (fp)((size), __FILE__, __LINE__)
#define malloc(size) chk_malloc((size), __FILE__, __LINE)
こうしといた方が安全か。
0270デフォルトの名無しさん
2005/09/19(月) 15:03:210271デフォルトの名無しさん
2005/09/19(月) 15:05:57C++ならともかく、Cでmalloc無しってどうすればいいんだよ。(calloc realloc をつかえとか言うなよ)
0272デフォルトの名無しさん
2005/09/19(月) 15:09:40API使えって句とかと。
0273デフォルトの名無しさん
2005/09/19(月) 15:10:300274デフォルトの名無しさん
2005/09/19(月) 15:10:43 ̄ ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄
______
/:::::::::::::::::::::\
/::::::::::::::::::::::::::::::::\
|:::::::::::::::: |
|::::::::::::::: ∪ \,, ,,/)
|::( 6::ー──◎─◎|
ノ::: (∵∴∪ ( ・ ・))
/ ∵ 3 丿 ブフィ
/\ U ___ノ
/ .\ ____ノ\
\______ノ .\
0275デフォルトの名無しさん
2005/09/19(月) 15:16:53realloc じゃないか? 上のアレ。
0276デフォルトの名無しさん
2005/09/19(月) 15:30:21スタックに予め大きく取って分ければ良いとか言ってたっけな。
そいつもかなり鬱陶しかった。
0277デフォルトの名無しさん
2005/09/19(月) 15:42:560278デフォルトの名無しさん
2005/09/19(月) 15:47:270279デフォルトの名無しさん
2005/09/19(月) 16:11:570280デフォルトの名無しさん
2005/09/19(月) 16:36:14お好きなように。プロジェクト単位で使い方のルールが統一されていると読み易くて宜しいかと。
0281デフォルトの名無しさん
2005/09/19(月) 16:47:540282デフォルトの名無しさん
2005/09/19(月) 16:55:19エラー時に、中途半端にデータが埋められるってのがないから。
でも、calloc はよく分からん。
何か、環境依存で問題があったりするんだろうか。
0283デフォルトの名無しさん
2005/09/19(月) 17:05:28デフォルトでは、Linux は楽観的メモリ配置戦略を用いている。
つまり、 malloc() が NULL でない値を返しても、そのメモリが
実際に利用可能であることが保証されない。これは本当にまずいバグである。
Linuxてこわいな。
0284デフォルトの名無しさん
2005/09/19(月) 17:10:290285デフォルトの名無しさん
2005/09/19(月) 17:11:210286デフォルトの名無しさん
2005/09/19(月) 17:21:43このメモリを割り当て過ぎる動作を以下のコマンドで無効にできる。
# echo 2 > /proc/sys/vm/overcommit_memory
0287デフォルトの名無しさん
2005/09/19(月) 17:30:15だから、ソフトウェアが普通に組まれてても、
コマンド発行するまで危険な動作をする可能性があるということでしょ。
素人がLinux構築するとバグだしまくりなのは、
素人が使うことを前提としたWindowsとはやはり違うということで。
ま、Linux単体で使う人もあまりいないでしょうけど、
Linuxを盲目的に信奉すると危険てことですね。
0288デフォルトの名無しさん
2005/09/19(月) 18:11:52はやくバグフィクスしろよ。
0289デフォルトの名無しさん
2005/09/19(月) 18:38:090290デフォルトの名無しさん
2005/09/19(月) 19:04:10やる気0だなw
0291デフォルトの名無しさん
2005/09/19(月) 19:11:58今まで1次元配列の方が早いだろうと思って多次元配列を1次元で書いてたんだが、>>199見る限り速度的にそんなに差はないってこと?
0292デフォルトの名無しさん
2005/09/19(月) 19:14:16あんま変なことしてると、
最適化がうまく効いてくれないかもしれないぞ。
0293デフォルトの名無しさん
2005/09/19(月) 19:16:59んなことが気になるぐらいならasmのソースでも比較すりゃいいじゃねえか
0294デフォルトの名無しさん
2005/09/19(月) 19:24:270295デフォルトの名無しさん
2005/09/19(月) 19:28:17人生が環境依存になりますがよろしいでしょうか?
0296デフォルトの名無しさん
2005/09/19(月) 19:54:15int ReturnValue[5][5];と宣言して
return ReturnValue;としたいのですが,
関数宣言の仕方が分かりません<m(__)m>
int** ThisFunction();これではだめでした!
このint**がエラーのようですが,正しくはどのように宣言するのでしょうか?
0297デフォルトの名無しさん
2005/09/19(月) 19:56:050298デフォルトの名無しさん
2005/09/19(月) 20:20:530299デフォルトの名無しさん
2005/09/19(月) 20:31:11一応型だけを見れば
int (*ThisFunction())[5];
か
typedef int ArrayType[5];
ArrayType* ThisFunction();
か
typedef int (*ReturnType)[5];
ReturnType ThisFunction();
で、int** がダメな理由は >>221 。
ただ、配列を内部変数として取ってるのに
そうやって返すことはできないぜ。
0300デフォルトの名無しさん
2005/09/19(月) 20:40:52int (*ThisFunction())[5];でできました!
ありがとうございます
全く予想付かない形でした
>>ただ、配列を内部変数として取ってるのに
>>そうやって返すことはできないぜ。
実際はクラスの中の変数を,Public関数から返します
0301デフォルトの名無しさん
2005/09/19(月) 21:08:29まあ、C++ 関係ない話だったからいいけどさ。
0302デフォルトの名無しさん
2005/09/19(月) 21:25:13ところでint型の配列を高速で初期化する方法はないのでしょうか?
int BigArray[100][100];
for(int x=0;x<100;x++){
for(int y=0;y<100;y++)
BigArray[x][y]=10;
}
↑これを高速化したいのです!
0303デフォルトの名無しさん
2005/09/19(月) 21:31:04memset使えばいいじゃないか
0304デフォルトの名無しさん
2005/09/19(月) 21:39:050305デフォルトの名無しさん
2005/09/19(月) 21:42:19memset はバイト単位じゃねぇか
0306デフォルトの名無しさん
2005/09/19(月) 21:43:01for(int i = 0; i < 10000; i++) {
BigArray[0][i] = 10;
}
で少しくらいは速くならないかな?
0307デフォルトの名無しさん
2005/09/19(月) 21:44:13int もバイト単位でアクセスできますが?
0308デフォルトの名無しさん
2005/09/19(月) 21:48:220309デフォルトの名無しさん
2005/09/19(月) 21:50:15これがはやいんじゃねーの?
0310デフォルトの名無しさん
2005/09/19(月) 21:52:17よく見ろ。0 じゃなくて 10 で埋めるんだぞ?
0311デフォルトの名無しさん
2005/09/19(月) 21:59:54void *memset(void *s, int c, size_t n);
で。
速度云々は別としてmemsetで問題ないと思う。
0312デフォルトの名無しさん
2005/09/19(月) 22:00:54w
0313デフォルトの名無しさん
2005/09/19(月) 22:02:36てことは、逆にキャラ配列で10 padding するには、0x0a0a0a0a で生めにゃならんのか?
そういう使い方したことないから、気づかんかった。
0314デフォルトの名無しさん
2005/09/19(月) 22:04:42何を言っとるんだw
c の型は int だけど、実際に使われるのは下位1バイトだけだぞ!
c の型が int なのは、標準関数の引数には char を使わないから(ポインタ除く)。
0315デフォルトの名無しさん
2005/09/19(月) 22:08:14memsetは0で初期化する場合はintにも使えますが,10では無理です
0316デフォルトの名無しさん
2005/09/19(月) 22:10:00だから、さっきからそう言ってるじゃないか。
0317デフォルトの名無しさん
2005/09/19(月) 22:13:18int BigArrayBuf[100][100];
for(int x=0;x<100;x++){
for(int y=0;y<100;y++)
BigArrayBuf[x][y]=10;
}
ってしといて、使うとこで
int BigArray[100][100];
memcpy(BigArray,BigArrayBif,sizeof(BigArray));
ってすりゃええやん
0318デフォルトの名無しさん
2005/09/19(月) 22:16:570319デフォルトの名無しさん
2005/09/19(月) 22:18:070320デフォルトの名無しさん
2005/09/19(月) 22:19:41代入の方が速い気がするけど、実測してみないと結論は出せぬ。
0321デフォルトの名無しさん
2005/09/19(月) 22:20:34でいいじゃん
10000個の要素はawkなりPerlなり前処理で
自動生成すればいい
0322デフォルトの名無しさん
2005/09/19(月) 22:25:16初期化は宣言と同時に行うものだよ
うざがれそうだが…
0323デフォルトの名無しさん
2005/09/19(月) 22:31:030324デフォルトの名無しさん
2005/09/19(月) 22:37:57作業としての初期化だ。
0325デフォルトの名無しさん
2005/09/19(月) 22:44:410326SSE2依存
2005/09/20(火) 02:49:10void foo()
{
__declspec(align(16)) int BigArray[100][100];
int i;
const __m128i v = { 10, 10, 10, 10 };
for ( i = 0; i < 100 * 100; i += 4 ) {
_mm_store_si128( (__m128i*)&(BigArray[0][i]) , v);
}
}
0327デフォルトの名無しさん
2005/09/20(火) 02:51:02約40KBバイナリファイルサイズが増えます
0328デフォルトの名無しさん
2005/09/20(火) 06:08:46scanfで数値を一文で横に入力するようにするにはどのようにプログラムすればいいでしょうか?
100 200 300 と入力する感じにしたいのです
よくわからなかったので
scanf("%d %d %d",&a,&b,&c)みたいにやってみたのですが
これだと縦に
100
200
300
と入力するようになってしまいます
やりかた教えてください
あと小数点つき123.45とか入力した場合
途中で終わってしまいます
小数点入り数値を入力しても大丈夫なやり方も教えてほしいです
0329デフォルトの名無しさん
2005/09/20(火) 06:24:07VC++スレの人だな
変換指定子が%d %d %dなら、「100 200 300」だろうと
「100[ret]200 300」でも「100[ret]200[ret]300」でも読み込めた希ガス
小数の場合は放り込む変数をfloatなりdoubleで用意して
変換指定子を%f
0330デフォルトの名無しさん
2005/09/20(火) 06:50:45ありがとうございます
とりあえず数値を入力して出力だけ出来るように今やってるんですが、現在こんな感じ
#include <stdio.h>
int main (void)
{
float a;
int b,c,d;
scanf("%f",&a);
scanf("%d %d %d",&b,&c,&d);
printf("%f %d %d %d",a,b,c,d);
return 0;
}
入力するのはa=123.45 b=100 c=200 d=300って感じです
出力すると123.45が123.449997になってしまいます
あと[ret]入れるのは数値を入力するときでしょうか?入れてみたらすごい数値がでちゃったり
できれば[ret]なしで横に入力させるようにしたいです
連投が返事がおそく(´・ω・`)
0331300
2005/09/20(火) 06:56:06横に入力まではできてました
あと残る問題は123.45を入れると123.49997って出るだけです
そのまま123.45って出したい
■ このスレッドは過去ログ倉庫に格納されています