繁体   English   中英

当程序运行正常时Valgrind大喊(C)

[英]Valgrind yelling when the program works perfectly fine (C)

我有一个程序(在其基本阶段)应该从stdin中获取文件,对其进行编码并将其打印到stdout。 无论我读入哪种类型的stdin,它似乎都可以正常工作。但是,Valgrind告诉我有一个问题:

==6508== Invalid read of size 4
==6508==    at 0x4009EC: insertObject (lzw.c:106)
==6508==    by 0x400B72: lzw_encode (lzw.c:228)
==6508==    by 0x40091D: main (lzw.c:48)
==6508==  Address 0x5203044 is 0 bytes after a block of size 65,540 alloc'd
==6508==    at 0x4C2845D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6508==    by 0x400D51: initialize (lzw.c:305)
==6508==    by 0x400AB3: lzw_encode (lzw.c:196)
==6508==    by 0x40091D: main (lzw.c:48)
==6508== 

以下是相关的代码段:

int lzw_encode ()
{
    table* hashtable;
    int counter=0;
    hashtable = initialize(); //line 196
    int code = -1;
    char k;
    if ((k=getc(stdin))==EOF)
    {
        return 0;
    }
    code = k;
    while ((k=getc(stdin))!=EOF)
    {
        if (HashSearch(hashtable, code, k)!=-1)
        {   
            code=HashSearch(hashtable, code, k);
        }
        else
        {  
            putBits(12, code);

            if (hash(code, k, hashtable->size)>4340)
            {
                counter=1;
            }
            if (counter==0)
            {
                hashtable = insertObject(hashtable, code, k); //line 228
            }

            code = HashSearch(hashtable, -1, k);

        }
    }
    if (code != 0)
    {
        printf ("%d\n", code);
    }
    /*if (!fp)
    {
        printf("????\n");
    }*/

    return 0;
}

InsertObject:

table *insertObject (table *h, int pref, char ch)
{
    struct node x;
    int i;
    if (ch < 0)
    {
        ch=4096-ch;
    }
    x.chr=ch;
    x.pref=pref;
    i = hash(pref, ch, h->size);
    while (h->hash[i].pref!=0)
    {
        i++;
    }
    if (i>4340)
    {
        return h;
    }
    h->hash[i]=x; //line 106
    return h;
}

初始化:

table *initialize ()
{
    table *hashtable = malloc(sizeof(table)); //Line 305
    //hashtable->hash = malloc (sizeof(struct node) * 4096);
    memset(hashtable, 0, sizeof(*hashtable));
    hashtable->size=4096;
    //hashtable->hash=malloc(sizeof(table));
    for (int i=0; i<4096; i++)
    {
        hashtable->hash[i].pref=-1;
        hashtable->hash[i].before=-1;
        hashtable->hash[i].after=-1;
        hashtable->hash[i].chr=0;
    }
    for (int i=0; i<256; i++)
    {
        hashtable->hash[i].chr=i+128;
    }
    //printf("Initialized\n");
    return hashtable;
}

我已经标记了valgrind中提到的行。

编辑:

这里是数据结构:

typedef struct hash_t table;

struct node {
    int pref;
    int before;
    int after;
    char chr;
};

struct hash_t {
    int size;
    struct node hash[4096];
};

EDIT2:确保我永远不会超过4096似乎已解决它。 但是,我发现了一个以前见过的valgrind错误:

==20137== Syscall param write(buf) points to uninitialised byte(s)
==20137==    at 0x4F198B0: __write_nocancel (in /usr/lib64/libc-2.17.so)
==20137==    by 0x4EA8E32: _IO_file_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.17.so)
==20137==    by 0x4EAA29B: _IO_do_write@@GLIBC_2.2.5 (in /usr/lib64/libc-2.17.so)
==20137==    by 0x4EABDE6: _IO_flush_all_lockp (in /usr/lib64/libc-2.17.so)
==20137==    by 0x4EABF39: _IO_cleanup (in /usr/lib64/libc-2.17.so)
==20137==    by 0x4E6AE0A: __run_exit_handlers (in /usr/lib64/libc-2.17.so)
==20137==    by 0x4E6AEA4: exit (in /usr/lib64/libc-2.17.so)
==20137==    by 0x4E53AFB: (below main) (in /usr/lib64/libc-2.17.so)
==20137==  Address 0x4023002 is not stack'd, malloc'd or (recently) free'd

基于此站点上的其他问题,当未初始化结构时,似乎会发生这种情况。 但是,我看不到任何单位化的结构。 这段代码是否存在这样的问题,还是应该在程序的其他地方查看?

insertObject第106行中,您尝试从地址hash[i]读取。 hash大小为4096,但仅在i > 4340以上的四行时才进行检查。 在您的程序执行期间, i可能取值介于4096和4340之间。

Valgrind输出的第一块通知您,您无法从地址hash + i * sizeof(struct node)读取请求的四个字节。

第二个块告诉您您尝试读取的地址刚好超出分配的大小为65,540的数组的末尾。 也就是说,实际上,您的h变量已传递给insertObject

有关常见Valgrind错误报告的说明,请参见例如http://valgrind.org/gallery/linux_mag.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM