2011-08-14 9 views
4

printfが計算された引数を格納するために利用できるメモリの上限はいくらですか? 引数を格納するために、(引数の変数を使用して)任意のコマンドで使用できる一般的なメモリサイズはどれくらいですか?printfの内部

例コード:

#include <stdio.h> 

#include <stdlib.h> 


int main(int argc, char *argv[]) 

{ 

//by default the decimal is considered as double 

float a = 0.9; 

//long double b = (long double)23455556668989898988988998898999.99 ; 

long double b = 5.32e-5; 

double z = 6789999000000.8999; 


//b = (long double)1.99999999; 

printf("float %f, \n double %lf,\n long double %Lf\n\n\n", b, b, b); 

printf("simple: long double %Lf, double %lf, float %f\n\n\n", b,b,b); 

printf(" sumi: float %f, double %lf, long double %Lf\n\n\n", z, z, z); 

printf("test2 for le/lg/lf: dbl f %Lf, double g %Lg, double e %Le\n\n\n", b, b, b); 

    system("PAUSE"); 

    return 0; 

} 
+0

...どちらかのサイズを超えているコードの例私は...これはコーディングだけで怠け者であるMSのprintfが何をするかは考えを伝えることはできませんが、私はそこに高品質のコードを期待していないよう: – Nik

+0

の#include を#include メインINT(INTのARGC、CHAR * ARGV []){ は//長いダブルB =(長二重)23455556668989898988988998898999.99。 long double b = 5.32e-5; double z = 6789999000000。8999; // b =(long double)1.99999999; printf( "float%f、\ nダブル%lf、\ nロングダブル%Lf \ n \ n \ n"、b、b、b); printf( "シンプル:ロング・ダブル%Lf、ダブル%lf、フロート%f \ n \ n \ n"、b、b、b); printf( "sum:float%f、double%lf、long double%Lf \ n \ n \ n"、z、z、z); printf( "test2 for le/lg/lf:dbl f%Lf、double g%Lg、double e%Le \ n \ n \ n"、b、b、b); システム( "PAUSE"); \t return 0; } – Nik

+0

「編集」リンクを使用して、コメントをコメントとして投稿するのではなく、質問にコードを追加することができます。 –

答えて

0

printfに渡すことができるタイプの印刷をサポートするための最小メモリ要件は、1535の指数がlong doubleであると仮定すると、スタックスペースの約6kです。任意の非浮動小数点型の場合、200バイト以下で得ることができます。

もちろん、ほとんどの現実的な実装は、ここで最大効率ではありません。 glibcは、少なくとも一部の形式ではprintfの一部としてmallocを実行します。したがって、予測できないエラーが発生します。限り

+0

また、私が最初の段落で引用した使い方「議論ごと」ではなく「ピーク使用量」である。 1つの引数が変換されて出力されると、処理中のデータを処理する必要がありません。 'printf'はちょうど次のものに進むことができます。メモリ使用量が引数の数に比例して増加する唯一の方法は、 'printf'が内部的にすべての引数、引数型、または書式指定子を格納する構造体を作るかどうかです。 glibcはいくつかの非標準的な拡張機能でこれを行いますが、POSIX i18n( '%N $'タイプ)形式の文字列処理にも役立ちます。 –

2

は特に制限はありません。過剰な#/引数の最大の危険は、誤ってスタックをオーバーフローさせることです。

"stackoverflow.com" のための偉大な質問が;-)

+0

私は実装を見つけることができるリンクを指定することはできますか? – Nik

+0

glibcまたは[uClibc](http://uclibc.org/)ソースを検索してください。 –

+0

Windows Cランタイムライブラリは、ソースコードを含むVisualStudioと共に提供されます。インストール時に適切なチェックボックスをチェックしてください。 LinuxまたはGNU Cライブラリは、http://www.gnu.org/software/libc/(ソースコードはもちろん)にあります。 – Codo

0

固定された制限はありません何。いくつかのシステムは、スタックの数バイト(おそらく128または256)しか持っていないものもあれば、それらのメガバイトを持つものもあります。ヒープを持つものもあれば、関数によって使われるものもあれば、そうでないものもあります。いくつかの内部関数は静的メモリを使用することがありますが、他の実装ではそうではありません。

+0

実装を見つけるためのリンクを指定できますか? – Nik

+0

@ニック:どのOS/libc? –

+0

windows 7、gccコンパイラ – Nik

1

通常、引数は呼び出しスタック上にあるため、単一のスレッドアプリケーションでは、主な制限はスタックのサイズになります。 Posixでは、getrlimits()を使用してそのサイズを検出するか、Bashビルトインulimitを使用できます。

もっと興味深いのは、結果として得られる文字列にどれくらいのメモリがあるか、割り振りを実行する必要があるかどうかです。

+0

なぜシングルスレッドに言及しましたか?マルチスレッドの場合、同じスタック引数が保持されます。 –

+0

本当にありません。マルチスレッドプログラムでは、各スレッドには独自のスタックがあり、通常はスタックの制限ではなく、プロセスの通常のメモリ制限から割り当てられます。 –

+0

ええ、すべてのスレッドが独自のスタックを持っているので、解析は少し複雑です。 –

0

これは実装とセットアップ(OS、設定など)によって異なります。一般に、ローカル変数と引数はスタックに格納され、スタックの大きさはプラットフォーム、個人設定などによって異なります。

大規模な値をスタックに格納するのは一般的ではありません。関数が他の関数を呼び出す場合は、スタックスペースなども必要です。

すべての実装でスタックを使用するわけではありませんし、かなり小さいかもしれません。

ローカルフレームに大きすぎる値を保存しないでください。

0

printfは何も保存する必要はありません。 これはこのように実装できます。 引数を取得し、フォーマットして出力するように出力します。