2016-05-16 10 views
0

マクロを使用して各メッセージにタイムスタンプとソースファイル名を追加するようなカスタムロギングシステムを維持しています。だから、のようなもの:C++で単一のグローバルchar *を作成する方法

AI_LOG("Hello %s", "World!"); 

をする可能性があります:

現在
(16.38) HelloWorld.cpp LOG: Hello World! 

、それはその後、スタック上のchar *バッファを作成し、バッファの先頭に出力の最初の部分を配置し、 snprintfを使用して出力を残りのバッファにコピーします。これはすべて動作しますが、スタックにバッファを作成することを除いて、十分なログステートメントを持つ十分なスタックがあり、バッファをかなり小さく(たとえば256文字)保持しないと、スタックオーバーフローが発生します。もっと長い文字列を出力する必要があるので、スタックにすべてのバッファを置くことはもう私のためには役に立たないでしょう。

その背景を念頭に置いて、私は非常に大きなもの(おそらく4K文字のようなもの)を作成する単一のグローバルchar配列に移動したいと思います。しかし、私の理解は、私はちょうど何かを言うならばということである:私の出力システムの.hファイルに

#define AI_OUTPUT_BUFFER_SIZE 4092 
char AI_OUTPUT_BUFFER[AI_OUTPUT_BUFFER_SIZE]; 

を、私はその.hファイルを含んでいるすべてのファイルで作成されている別のバッファを持つことのリスクを実行します。それは本当の問題ですか?もしそうなら、私が望む単一のバッファを得る良い(コンパイラに依存しない、C++ 98に準拠した、Boost以外の)方法がありますか?

私は、ヘッダーでこれを行うに傾いた:

#define AI_OUTPUT_BUFFER_SIZE 4096 
class AIOutputBuffer 
{ 
public: 
    static char buffer[AI_OUTPUT_BUFFER_SIZE]; 
}; 

そして私ができるの.cppに:

char GAIA::AIOutputBuffer::buffer[AI_OUTPUT_BUFFER_SIZE]; 

しかし、それは私のリンカ頭痛を与えている...たぶん私はよそれはまだ正しく行っていないのですか?

そして、人々がそれを提案する前に、私はおそらくそれを文字列やストリームを使用するように書き換えることができました...しかし、私は本当にシステム全体を書き直したいとは思いませんし、それ。このシステムはうまく動作し、私に多くの柔軟性を与えます。メモリ使用量の問題を処理するだけです。

+0

なぜ、バッファなしでcoutなどを呼び出すマクロを使用しないのですか? –

+0

なぜマクロを使うのですか?コンパイラがあなたのロギング関数をインライン化しないならば、コードをインラインにするのは良い考えです。 – user4581301

+1

@ user4581301機能を使用している場合、回線情報やファイル情報にアクセスすることはできません。 –

答えて

0

私はexternを使って、魅力的なように働いていました(感謝Dmitri!)。だから、ヘッダーに:.cppファイルで、その後

#define AI_OUTPUT_BUFFER_SIZE 256 
extern char AI_OUTPUT_BUFFER[AI_OUTPUT_BUFFER_SIZE]; 

+0

警告:クライアントコードで複数のスレッドが実行されている場合、同時に2つのメッセージがバッファにヒットし、互いに破棄することは非常に簡単です。 – user4581301

+0

ええ、これまでのところ、私はシングルスレッドです。それが変わると...これは多くの心配の1つになります。 :) –

0

あなたはあなたの問題を解決しながら、メモリ管理のためのstd::stringに依存してよりよい解決策があります。また、マルチスレッド環境ではうまく動作します。

#include <string> 
#include <cstdarg> 

std::string va(const char* fmt, ...) 
{ 
    // make sure your stack can handle a one-time allocation of a buffer of this size 
    const auto BUFFER_SIZE = 8192; 

    // ...unless you know you're not going to call this from multiple threads; 
    // then you can make this buffer static and the size can be increased 
    char buffer[BUFFER_SIZE]; 

    va_list args; 
    va_start(args, fmt); 
    std::vsnprintf(buffer, sizeof(buffer), fmt, args); 
    va_end(args); 
    buffer[sizeof(buffer) - 1] = '\0'; 

    return buffer; 
} 

使用法:ここでは珍しい何も:auto logMsg = va("Hello %s", "World!");

アイデアは、オールドスクールsnprintfを使用しますが、std::stringは、メモリ管理の世話をさせることです。

+0

@deviantfan関数の戻り値は(型の) 'std :: string'です。 – szczurcio

+0

Uh ...申し訳ありませんが、私はそれを見ていませんでした:D – deviantfan

+0

OPは明らかにスタック割り当てを避けようとしています(質問参照) - おそらく彼はメモリが制約されている組み込みシステムなどにあります。 *「もしバッファをかなり小さく(例えば256文字)にしないと、スタックオーバーフローが発生する可能性があります」*。 –

関連する問題