C中的变量参数在Valgrind中创建错误

0as*_*am0 0 c variables valgrind arguments realloc

我试图运行一个使用函数的程序concat_str.它可以将多个参数作为字符串,参数的结尾表示为"quit".我的功能代码如下:

char *concat_str(char *str1, ...)
{
    va_list pstr;
    char *minion = NULL, *temp = NULL;
    minion = (char*) malloc (sizeof(str1));
    strcpy (minion,str1);
    va_start (pstr, str1);
    if ( strcmp ("quit",str1) == 0)
    {
        va_end (pstr);
        return minion;
    }
    while (1)
    {
        temp = va_arg (pstr, char *);
        if ( strcmp ("quit", temp) == 0)
        {
            break;
        }
        minion = (char*) realloc (minion, sizeof(temp));
        strncat (minion,temp,sizeof(temp));
    }
    va_end (pstr);
    return minion;
}
Run Code Online (Sandbox Code Playgroud)

对此的调用声明将是:

char *result;
result = concat_str("hello", "hai", "how", "are", "you", "quit");
Run Code Online (Sandbox Code Playgroud)

我得到了正确的输出.但是当我valgrindmemcheck工具运行它时,我遇到了很多错误.错误如下:

==2635== Invalid write of size 1
==2635==    at 0x4A065D3: strncat (mc_replace_strmem.c:218)
==2635==    by 0x400A7E: concat_str (var_fun.c:23)
==2635==    by 0x400757: main (var_main.c:15)
==2635==  Address 0x4C33038 is 0 bytes after a block of size 8 alloc'd
==2635==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==2635==    by 0x400A5F: concat_str (var_fun.c:22)
==2635==    by 0x400757: main (var_main.c:15)
==2635==
==2635== Invalid read of size 1
==2635==    at 0x4A06594: strncat (mc_replace_strmem.c:218)
==2635==    by 0x400A7E: concat_str (var_fun.c:23)
==2635==    by 0x400757: main (var_main.c:15)
==2635==  Address 0x4C33038 is 0 bytes after a block of size 8 alloc'd
==2635==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==2635==    by 0x400A5F: concat_str (var_fun.c:22)
==2635==    by 0x400757: main (var_main.c:15)
==2635==
==2635== Invalid write of size 1
==2635==    at 0x4A065BF: strncat (mc_replace_strmem.c:218)
==2635==    by 0x400A7E: concat_str (var_fun.c:23)
==2635==    by 0x400757: main (var_main.c:15)
==2635==  Address 0x4C33038 is 0 bytes after a block of size 8 alloc'd
==2635==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==2635==    by 0x400A5F: concat_str (var_fun.c:22)
==2635==    by 0x400757: main (var_main.c:15)

==2635==
==2635== Invalid read of size 1
==2635==    at 0x4A066D4: strlen (mc_replace_strmem.c:246)
==2635==    by 0x32DAC46B18: vfprintf (in /lib64/libc-2.5.so)
==2635==    by 0x32DAC4D3A9: printf (in /lib64/libc-2.5.so)
==2635==    by 0x40076E: main (var_main.c:16)
==2635==  Address 0x4C33038 is 0 bytes after a block of size 8 alloc'd
==2635==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==2635==    by 0x400A5F: concat_str (var_fun.c:22)
==2635==    by 0x400757: main (var_main.c:15)
==2635==
==2635== Invalid read of size 1
==2635==    at 0x32DAC6CE09: _IO_file_xsputn@@GLIBC_2.2.5 (in /lib64/libc-2.5.so)
==2635==    by 0x32DAC464B2: vfprintf (in /lib64/libc-2.5.so)
==2635==    by 0x32DAC4D3A9: printf (in /lib64/libc-2.5.so)
==2635==    by 0x40076E: main (var_main.c:16)
==2635==  Address 0x4C33040 is 8 bytes after a block of size 8 alloc'd
==2635==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==2635==    by 0x400A5F: concat_str (var_fun.c:22)
==2635==    by 0x400757: main (var_main.c:15)
==2635==
==2635== Invalid read of size 1
==2635==    at 0x32DAC6CE1C: _IO_file_xsputn@@GLIBC_2.2.5 (in /lib64/libc-2.5.so)
==2635==    by 0x32DAC464B2: vfprintf (in /lib64/libc-2.5.so)
==2635==    by 0x32DAC4D3A9: printf (in /lib64/libc-2.5.so)
==2635==    by 0x40076E: main (var_main.c:16)
==2635==  Address 0x4C3303F is 7 bytes after a block of size 8 alloc'd
==2635==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==2635==    by 0x400A5F: concat_str (var_fun.c:22)
==2635==    by 0x400757: main (var_main.c:15)
==2635==
==2635== Invalid read of size 1
==2635==    at 0x32DAC6CD66: _IO_file_xsputn@@GLIBC_2.2.5 (in /lib64/libc-2.5.so)
==2635==    by 0x32DAC464B2: vfprintf (in /lib64/libc-2.5.so)
==2635==    by 0x32DAC4D3A9: printf (in /lib64/libc-2.5.so)
==2635==    by 0x40076E: main (var_main.c:16)
==2635==  Address 0x4C33038 is 0 bytes after a block of size 8 alloc'd
==2635==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==2635==    by 0x400A5F: concat_str (var_fun.c:22)
==2635==    by 0x400757: main (var_main.c:15)
==2635==
==2635== Invalid read of size 1
==2635==    at 0x32DAC6CD7A: _IO_file_xsputn@@GLIBC_2.2.5 (in /lib64/libc-2.5.so)
==2635==    by 0x32DAC464B2: vfprintf (in /lib64/libc-2.5.so)
==2635==    by 0x32DAC4D3A9: printf (in /lib64/libc-2.5.so)
==2635==    by 0x40076E: main (var_main.c:16)
==2635==  Address 0x4C33039 is 1 bytes after a block of size 8 alloc'd
==2635==    at 0x4A0590B: realloc (vg_replace_malloc.c:306)
==2635==    by 0x400A5F: concat_str (var_fun.c:22)
==2635==    by 0x400757: main (var_main.c:15)
Run Code Online (Sandbox Code Playgroud)

错误来源(我自己的扣除):

第22行: minion = (char*) realloc (minion, sizeof(temp));

Realloc返回新块指针的地址minion.但旧块会产生问题.

我试过的事情:

  1. 我换strncat (minion,temp,sizeof(temp));strncat (minion,temp,sizeof(temp) + 10);.这减少了一些错误.但是如果字符串参数很长,我又会遇到同样的错误.顺便说一句,我不明白这是如何解决这个问题的.

  2. 我换minion = (char*) realloc (minion, sizeof(temp));

    char t = NULL; t = minion; minion =(char)realloc(t,sizeof(temp)); free(t);

请告诉我,如果我的错误来源是正确的,并建议我应该怎么做才能解决这个问题.

M O*_*ehm 5

表达方式

sizeof(str1)
Run Code Online (Sandbox Code Playgroud)

将产生指针的大小,而不是字符串长度.你应该分配

minion = malloc(strlen(str1) + 1);
Run Code Online (Sandbox Code Playgroud)

对于重新分配,您必须提供整个阵列的大小,而不仅是新分配的存储,因此您应该跟踪字符串长度.

最后,一个风格提示:通常使用NULLendinel值来终止字符串列表,而不是使用像你这样的任意文字"quit".