C++ 字符*组合

C++ 字符*组合,c++,char,C++,Char,我更喜欢char*而不是std::string,所以我编写了一个结合char指针的函数。我创建了一个新项目并进行了测试。它很好用。但是当我试图在一些更大的GUI项目中使用它时,我的程序崩溃了 下面是一个示例(工作)代码: #包括 #包括 char*StringJoin(常量char*String,常量char*…) { va_列表ArgList; va_开始(ArgList,字符串); std::向量字符串数据; std::向量串; StringData.push_back(字符串); unsi

我更喜欢
char*
而不是
std::string
,所以我编写了一个结合char指针的函数。我创建了一个新项目并进行了测试。它很好用。但是当我试图在一些更大的GUI项目中使用它时,我的程序崩溃了

下面是一个示例(工作)代码:

#包括
#包括
char*StringJoin(常量char*String,常量char*…)
{
va_列表ArgList;
va_开始(ArgList,字符串);
std::向量字符串数据;
std::向量串;
StringData.push_back(字符串);
unsigned int SingleLength=strlen(字符串);
StringLen.向后推(单长度);
无符号整数总长度=单长度;
而(1)
{
常量字符*Val=va_arg(ArgList,常量字符*);
如果(!Val)
打破
StringData.push_back(Val);
SingleLength=strlen(Val);
StringLen.push_back(SingleLength);//在较大的项目中,它在这里崩溃
总长度+=单长度;
}
va_end(ArgList);
char*NewString=新字符[总长度+1];
unsigned int VectorSize=StringData.size();
无符号整数NewLength=0;
for(无符号int元素=0;元素

我的代码安全稳定吗?

您不能使用
!Val
条件:

const char* Val = va_arg(ArgList, const char*);
if (!Val)
    break;

使用变量参数列表时,您需要确切地知道传递了多少个参数,或者(更新)何时停止处理参数,例如使用
NULL
/
nullptr
(或任何其他)

如果编译器支持,您肯定应该使用变量模板

下面这个非常简单的函数接受任意数量的字符串,并将其连接到一个循环中。它支持参数的
std::string
char*
(甚至混合):


“我更喜欢
char*
而不是
std::string
”-也许您可以重新考虑您的偏好。如果您停止处理指针,让友好类型为您管理内存,那么随机崩溃就会少得多。由于代码无法编译,我不会说它正常工作……如果您坚持使用
std::string
,而不是尝试使用
char*
,那么您的代码将只有原来的一半大小,并且会更加健壮。这很愚蠢,您想使用char*但正在使用std::vector?只要使用std::string,然后在需要c API的const char*时调用std::string::c_str()。
但是当我尝试在一些更大的GUI项目中使用它时,
以及如何处理这个更大的GUI应用程序中潜在的内存泄漏?在你发布的例子中,你甚至没有处理明显的漏洞。那不是真的。终止的参数序列也是一个选项。例如,一些POSIX
exec…
函数使用此约定将参数和环境传递给子进程。当然,如果你测试一个
!Val
,调用函数时必须提供
nullptr
。如果我像这样添加NULL作为最后一个参数会怎么样?那么您的条件就会满足。@user3786178,有一个问题。当您调用一个参数列表以省略号结尾的函数时,编译器无法知道对应的参数将是哪种类型,只能进行类型的基本转换。在C++中,<代码> null <代码>定义为<代码> 0 >代码>,因此是<代码> int <代码>常数,而不是指针!在指针大小与
int
相同的机器上,您不会注意到差异。但是在象x64这样的体系结构上,指针大于
int
s,您的程序很可能会崩溃。与
a+b+c+d`相比,
StringJoin(a,b,c,d)有什么好处?需要更多的代码、更多的编译时间或更晦涩难懂的阅读:-)@Klaus好吧,OP想要这样一个函数;)你是对的!但是如果他真的想要的是
char*
而不是
std::string
,你不能用
std::unique\u ptr
:-)来回答
const char* Val = va_arg(ArgList, const char*);
if (!Val)
    break;
template<class ...Strings>
std::string StringJoin(Strings ...strings) {
    std::string joined;
    for (auto s : { strings... })
        joined += s;
    return joined;
}
template<class ...Strings>
std::unique_ptr<char[]> StringJoin(Strings ...strings) {
    std::string joined;
    for (auto s : { strings... })
        joined += s;

    std::unique_ptr<char[]> buf(new char[joined.size() + 1]);
    memcpy(buf.get(), joined.data(), joined.size());
    buf[joined.size()] = '\0';
    return buf;
}