【问题标题】:Program debugging using Valgrind使用 Valgrind 进行程序调试
【发布时间】:2018-04-14 04:36:47
【问题描述】:

我正在尝试解决“将数字乘以 11”的问题。数字可以是任意长的。我收到 SIGABRT 错误。

我尝试使用 valgrind 进行调试,但我不知道如何解决(在 stackoverflow 上看到很多关于 valgrind 的问题,但没有成功)。自上周以来,我一直被这个问题困扰。

代码是:

#include <stdio.h>
#include <stdlib.h>
#define CHUNK 10

void get_input(char *val,int *i){
    char ch,*tmp=NULL;
    int size;
    size=CHUNK;
    while(ch=getc(stdin),ch!=EOF && ch!='\n'){
        val[(*i)++]=ch;
        if(*i>=size){
            size+=CHUNK;
            tmp=realloc(val,size);
            if(!tmp){
                free(val);
                val=NULL;
                break;
            }
            val=tmp;
        }
    }
    val[*i]='\0';
}

void mul_11(char *val,int *i){
    int *digit,iter,j,carry=0,num,temp;
    iter=*i;
    digit=(int*)malloc((iter+2)*sizeof(int));
    for(j=iter-1;j>=0;j--){
        temp=val[j]-'0';
        num=temp*11+carry;
        digit[j+2]=num%10;
        carry=num/10;
    }
    digit[1]=carry%10;
    digit[0]=carry/10;
    if(digit[0]==0)
        temp=1;
    else
        temp=0;

    for(j=temp;j<=iter+1;j++)
        printf("%d",digit[j]);
    free(digit);
    digit=NULL;
    *i=0;
}
int main() {
    int t,i=0;
    char *val=NULL;
    scanf("%d ",&t);
    while(t--){
        val=(char*)malloc(CHUNK*sizeof(char));
            get_input(val,&i);
            mul_11(val,&i);
            printf("\n");
        free(val);
        val=NULL;
    }
    return 0;
}

完整的输入代码可以在Geeksforgeeks code here找到

Valgrind 错误:

5555555555555555555555555555555555555
==2349== Invalid read of size 1
==2349==    at 0x4008CE: mul_11 (mul11.c:30)
==2349==    by 0x400A8A: main (mul11.c:55)
==2349==  Address 0x52044a4 is 20 bytes after a block of size 16 in arena "client"
==2349== 
6111111105-3-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-6-60-8
==2349== Invalid free() / delete / delete[] / realloc()
==2349==    at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2349==    by 0x400AA0: main (mul11.c:57)
==2349==  Address 0x5204480 is 0 bytes inside a block of size 10 free'd
==2349==    at 0x4C2FD5F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2349==    by 0x400809: get_input (mul11.c:13)
==2349==    by 0x400A77: main (mul11.c:54)
==2349==  Block was alloc'd at
==2349==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2349==    by 0x400A60: main (mul11.c:53)
==2349== 

【问题讨论】:

  • 你没有把所有的代码,因为...?法格尼数在这里不是很有用。
  • 请尝试创建一个Minimal, Complete, and Verifiable Example 并向我们展示。 Valgrind 甚至不会报告您显示的函数中的问题。
  • 因为那将是一个很长的帖子
  • 您可以将代码上传到 pastebin 之类的网站,并在您的问题中链接到它。
  • @yogi 您应该开始了解函数返回的内容以及预期的参数类型。我建议你打开你的 GCC 标志。试试这个gcc-7 -Wpedantic -std=c11 -Wall -Wextra -Werror -Wstrict-prototypes -Wmissing-prototypes -Wmisleading-indentation -Wduplicated-cond -Wold-style-definition -Wconversion -Wshadow -Winit-self -Wfloat-equal -Wwrite-strings -O0 -g检查 =>> This for more about what GCC reports on your Code

标签: c valgrind


【解决方案1】:

如果get_input 重新分配你的val 并获得一个新地址,调用者(main) 将不会被告知val 的值已变为无效(realloc 已释放它)。 mul_11 将使用释放的内存,然后main 将第二次释放它。

一个解决方案是发送一个指向地址的指针,如果函数可以重新分配它,那么调用者就会得到新的值。

void get_input(char **valp,int *i){
 char *val = *valp;
...
 val = realloc ...
 *valp = val;
...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    • 1970-01-01
    相关资源
    最近更新 更多