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

0aslam0

我试图运行一个使用功能的程序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;
}

相同的调用语句为:

char *result;
result = concat_str("hello", "hai", "how", "are", "you", "quit");

我确实得到正确的输出。但是当我valgrind使用memcheck工具运行它时,我遇到了很多错误。错误如下:

==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)

错误来源(我自己的推论):

第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 =(char)重新分配(t,sizeof(temp)); 免费(t);

如果我的错误来源正确,请告诉我,并提出解决该问题的建议。

欧姆

表达方式

sizeof(str1)

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

minion = malloc(strlen(str1) + 1);

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

最后,是一种风格上的提示:通常,将其NULL用作哨兵值来终止字符串列表,而不是使用诸如your的任意文字"quit"

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C中的可变参数函数

来自分类Dev

C 函数中的可变参数

来自分类Dev

读取文件时valgrind中的错误-C

来自分类Dev

ANSI C中的可变参数宏替代

来自分类Dev

C ++ 11中的定长可变参数包

来自分类Dev

C ++中的嵌套可变参数函数

来自分类Dev

C中可变数量的参数?

来自分类Dev

在C ++中的可变参数模板中获取可变参数size_t ...参数的总和

来自分类Dev

在C ++中的可变参数模板中获取可变参数size_t ...参数的总和

来自分类Dev

宏中的可变参数

来自分类Dev

VS2013中的可变参数模板分辨率-错误C3520

来自分类Dev

以数组为参数在C ++中调用可变参数函数

来自分类Dev

检查参数是否在C的可变参数宏中传递

来自分类Dev

从C中可变参数函数的参数确定类型

来自分类Dev

C ++中没有参数可变参数模板函数

来自分类Dev

将参数传递给C中的可变参数函数

来自分类Dev

从C中可变参数函数的参数确定类型

来自分类Dev

可变参数模板错误:“实例化中”(gcc 9.2)

来自分类Dev

查询中的laravel 5.4 可变参数,给出错误结果?

来自分类Dev

“无法创建可变参数元组”错误

来自分类Dev

无法抑制valgrind中的错误

来自分类Dev

使用Valgrind在C中无效读取大小8的分段错误

来自分类Dev

在glibc上的valgrind输出在C ++中检测到错误

来自分类Dev

函数C中的char **和valgrind条件跳转错误

来自分类Dev

在 C 中实现拼写检查器:Valgrind 报告内存错误

来自分类Dev

C ++可变参数模板在可变参数宏中起作用

来自分类Dev

在C中的函数参数中创建数组

来自分类Dev

函数中参数的可变顺序

来自分类Dev

Swift中的可变参数方法