简体   繁体   English

如何在C ++中创建单个全局char *

[英]How to create a single global char* in C++

I am maintaining a custom logging system that uses macros to do things like append a timestamp and source file name to each message. 我正在维护一个自定义日志记录系统,该系统使用宏来执行诸如将时间戳和源文件名附加到每个消息的操作。 So something like: 所以像这样:

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

might result in: 可能会导致:

(16.38) HelloWorld.cpp LOG: Hello World!

Currently, it creates a char* buffer on the stack, places the initial part of the output into the beginning of the buffer, and then uses snprintf to copy the output into the remainder of the buffer. 当前,它在堆栈上创建一个char *缓冲区,将输出的初始部分放入缓冲区的开头,然后使用snprintf将输出复制到缓冲区的其余部分。 This all works... except that it creates the buffer on the stack, and if I have a deep enough stack with enough log statements and I don't keep the buffer quite small (eg 256 characters), I can get stack overflows. 所有这些工作...除了在堆栈上创建缓冲区外,如果我的堆栈足够深且有足够的日志语句,并且我没有将缓冲区保持得很小(例如256个字符),则可能会导致堆栈溢出。 I now have a need to output much longer strings, so putting all those buffers on the stack isn't going to work for me anymore. 现在,我需要输出更长的字符串,因此将所有这些缓冲区放在堆栈上对我来说不再有用。

With that background in mind... I'd like to move to a single global char array, which I will make quite big (probably something like 4K characters to start). 考虑到这种背景...我想转到一个单一的全局char数组,该数组将变得很大(可能以4K字符开头)。 However, my understanding is that if I just say something like: 但是,我的理解是,如果我只说以下内容:

#define AI_OUTPUT_BUFFER_SIZE 4092
char AI_OUTPUT_BUFFER[AI_OUTPUT_BUFFER_SIZE];

in my output system's .h file, then I run the risk of having a separate buffer being created by every file that includes that .h file. 在我的输出系统的.h文件中,则冒着由包含该.h文件的每个文件创建一个单独的缓冲区的风险。 Is that a real problem? 这是一个真正的问题吗? If so, is there a good (compiler-agnostic, C++98 compliant, non-Boost-using) way to get the single buffer that I want? 如果是这样,是否有一种好方法(与编译器无关,C ++ 98兼容,不使用Boost的方法)来获取所需的单个缓冲区?

I was leaning toward doing this in the header: 我倾向于在标题中执行此操作:

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

And then in the .cpp I can: 然后在.cpp文件中,我可以:

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

But that's giving me linker headaches... Maybe I'm not quite doing it right yet? 但这让我感到连接器头痛……也许我还不太正确呢?

And before people suggest it... yes, I could probably rewrite it to use strings or streams... but I don't really want to rewrite the whole system, nor do I have the time and resources to do that. 在人们建议它之前……是的,我可能可以重写它以使用字符串或流……但是我真的不想重写整个系统,也没有时间和资源来做到这一点。 This system works well and gives me a lot of flexibility - I just need to handle the memory usage problem. 该系统运行良好,并给我很大的灵活性-我只需要处理内存使用问题。

From the comments (thanks Dmitri!) I used extern, and it worked like a charm. 从评论中(感谢Dmitri!),我使用了extern,它像一个魅力一样起作用。 So in the header: 所以在标题中:

#define AI_OUTPUT_BUFFER_SIZE 256
extern char AI_OUTPUT_BUFFER[AI_OUTPUT_BUFFER_SIZE];

then in the .cpp: 然后在.cpp中:

char AI_OUTPUT_BUFFER[AI_OUTPUT_BUFFER_SIZE];

While you solved your problem, there's a nicer solution that relies on std::string for memory management. 解决问题的同时,还有一个更好的解决方案,它依赖std::string进行内存管理。 Also, it works perfectly well in a multithreaded environment. 而且,它在多线程环境中也能很好地工作。

The idea is to use the oldschool snprintf but let std::string take care of memory management: 这个想法是使用oldschool snprintf但让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;
}

Usage: nothing unusual here: auto logMsg = va("Hello %s", "World!"); 用法:这里没有什么异常: auto logMsg = va("Hello %s", "World!"); .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM