0

[编辑]插入的 NULL 在样本中终止

我有一个函数接收以 ava_list结尾的 a NULL。我将每个字符串连接到char*被调用的joinedString. 函数按预期工作,除非我joinedString每次调用此函数时都会增加它的大小。我的意思是保留以前的字符串并加入新字符串。

示例:第一次调用:

ShowMsg(style1, "a", "s", "d", NULL);

产生的结果:“asd”

第二次调用:

ShowMsg(style1, "w", "w", "q", NULL);

产生的结果:“asdwwq”

这种行为很奇怪,因为每次调用此函数时joinedString都会初始化。va_list 是否保存以前使用的值?我使用的是 C,而不是 C++,而且我知道,使用 std::string 会容易得多。

int ShowMsg(MSGBOXSTYLE msgStyle, char* str, ...)
{
    char* title = "", *joinedString = "", *theArg = "";
    wchar_t* convertedTitle = "", *convertedString = "";

    va_list args;
    theArg = str;
    va_start( args, str );
        while(theArg != NULL)
        {
            if(msgStyle == WARN)
            {
                title = theArg;
            }
            else
            {
                strcat( joinedString, theArg );
                strcat( joinedString, "\n\r" );
            }
            theArg = va_arg(args, char*);
        }
    va_end(args);
    ...
    convertedTitle = (wchar_t*)malloc((strlen(title)+1)*sizeof(wchar_t));
    convertedString = (wchar_t*)malloc((strlen(joinedString)+1)*sizeof(wchar_t));
    mbstowcs( convertedTitle, title, strlen(title)+1 );
    mbstowcs( convertedString, joinedString, strlen(joinedString)+1 );
    ...
    free(convertedTitle);
    free(convertedString);
}
4

2 回答 2

3

char *joinedString = ""表示joinedString 指向一个只读的1 字节字符数组。

您不应该写入那部分内存。它会在许多系统上崩溃。此外,即使你可以,当你用 写到数组的末尾时strcat( joinedString, theArg );,你会调用未定义的行为。

于 2013-07-31T16:14:07.907 回答
3

那是因为你不能像那样初始化字符串。您的初始化程序char* joinedString = ""正在初始化指针joinedString以指向程序开头的特定内存地址,该地址由一个空字符串组成。

然后,第一次调用该函数时,joinedString设置为指向那个仍然为空的内存区域。然后,您将一些字符放在那里并退出。

下次你开始时,角色仍然在那里。您唯一初始化的是指针,而不是实际数据。strcat然后将您的新参数附加到已填充字符串的末尾!

这应该是段错误,实际上我对您的程序正在输出任何内容印象深刻。它可能只是工作,因为你只使用几个字节,所以你不会覆盖太多。

要修复它,使用 malloc 初始化joinedString:

char* joinedString = malloc(MAX_LENGTH * sizeof(*joinedString));
joinedString[0] = '\0'; // Initialize to an empty string

然后在你的函数结束时,释放那个内存

free(joinedString);
于 2013-07-31T16:16:03.237 回答