Valgrind 块丢失

Valgrind Block are Lost

我试图理解为什么使用 valgrind 后的代码是错误的。问题显然是在函数 destroy_poli 中,我这样说是因为当我评论主函数的这一部分时

poli ** p = (poli **) malloc( sizeof( poli *) * npols );
for(k=0;k<npols;k++) {
    p[k] = new_poli( nvars, w  );
}
for(k=0;k<npols;k++)
    destroy_poli(p[k]);
free(p);

我用 valgrind 得到 0 个错误。请你能帮助理解我的错误在哪里吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bits.h"
#include "parsemap.h"
#include "galois.h"
#define ANF 1
#define pos(i,j) (((1+i)*i)/2 + j)
int *table_red;
typedef struct _mono {
    int w;
    char ** v;
} mono;

typedef struct _poli {
    int nvars;
    mono ** p;
} poli;

void destroy_mono(mono * m){
    int i=0;
    for(i=0;i<2*(m->w);i++)
        free(m->v[i]);
    free(m->v);

}

void destroy_poli(poli * p){
    int nvars = p->nvars;
    int i;
    for(i=0;i<((nvars+1)*nvars)/2;i++)
        destroy_mono(p->p[i]);
    free(p->p);
}

mono * new_mono( int w, int idx ) {
    int i;
    mono * r = (mono *) malloc( sizeof(mono) );
    r->w = w;
    r->v = (char **) malloc( sizeof(char *)*( 2*w ) );
    for( i = 0; i < 2*w; i++ ) {
        r->v[i] = (char *) malloc( sizeof(char )*( 4096 ) );
        r->v[i][0] = 0;
    }

    return r;
}

poli * new_poli( int nvars, int w  ) {
    poli * p = (poli *) malloc( sizeof(poli) );
    p->nvars = nvars;

    int i,j;
    nvars++;
    p->p = (mono **) malloc( sizeof( mono * ) * ((nvars+1)*nvars)/2);
    nvars--;
    for(i=0; i < nvars; i++ )
    for(j=0; j <=i; j++ )       
            p->p[pos(i,j)] = new_mono( w, i );
    }
   return p;
}

void create_table( int w ) {
    table_red = (int *) malloc( sizeof( int ) * 2 * w );
    int i, j, a, b;
    for(i=0;i<2*w;i++) {
        table_red[i] = mod( (1 << i), w );
    }
}
int ** read_input( int * npols, int * nvars, int * w, int ** enc ) {
    int i, j;
    *npols = 1;
    *nvars = 1;
    int nv = *nvars + 1;
    int np = *npols;
    *enc = (int *) malloc( sizeof( int) * np );
    for(i=0; i < np; i++ ) {
        (*enc)[i] = 0;
    }
    int ** coefs = (int **) malloc( sizeof( int *) * np );
    for(i=0; i < np; i++ ) {
        coefs[i] =  (int *) malloc( sizeof( int) * ((nv+1)*nv)/2 );
        for(j=0; j < ((nv+1)*nv)/2; j++)
        coefs[i][j] = 0;
    }

    return coefs;
}


int main(int argc, char ** argv) {
    int nvars;
    int npols;
    int i;
    int w = 2, *enc;

    int ** coefs = read_input( &npols, &nvars, &w, &enc );
    int k, j;
    create_table( w );
    npols = 1;
    poli ** p = (poli **) malloc( sizeof( poli *) * npols );
    for(k=0;k<npols;k++) {
        p[k] = new_poli( nvars, w  );
    }
    for(k=0;k<npols;k++)
        destroy_poli(p[k]);
    free(p);

    for(i=0; i < npols; i++ )
        free(coefs[i]);
    free(coefs);

    free(enc);
    return 0;
}

==24066== 16 bytes in 1 blocks are definitely lost in loss record 2 of 3
==24066==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24066==    by 0x400CE8: new_poli (in /home/grados-sanchez/workspace/mq2sat/mq2sat/mq2sat)
==24066==    by 0x400FD7: main (in /home/grados-sanchez/workspace/mq2sat/mq2sat/mq2sat)
==24066== 
==24066== 16 bytes in 1 blocks are definitely lost in loss record 3 of 3
==24066==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==24066==    by 0x400C46: new_mono (in /home/grados-sanchez/workspace/mq2sat/mq2sat/mq2sat)
==24066==    by 0x400D70: new_poli (in /home/grados-sanchez/workspace/mq2sat/mq2sat/mq2sat)
==24066==    by 0x400FD7: main (in /home/grados-sanchez/workspace/mq2sat/mq2sat/mq2sat)
==24066== 

您在 destroy_poli() 中缺少 free(p),在 destroy_mono() 中缺少 free(m)。我能够通过使用 -g 进行编译并使用 valgrind 检查分配泄漏指针的行号来确定跟踪它让我找到了问题。我做的另一件事是以可以调试和维护的方式编写代码,请检查并告诉我是否值得付出努力

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define ANF 1
#define pos(i, j) (((1 + (i)) * (i)) / 2 + (j))

int *table_red;
typedef struct _mono
{
    int w;
    char **v;
} mono;

typedef struct _poli
{
    int nvars;
    mono **p;
} poli;

void
destroy_mono(mono *m)
{
    if (m == NULL)
        return;
    for (int i = 0 ; i < 2 * m->w ; i++)
        free(m->v[i]);
    free(m->v);
    free(m);
}

void
destroy_poli(poli *p)
{
    if (p == NULL)
        return;
    for (int i = 0 ; i < ((p->nvars + 1) * p->nvars) / 2 ; i++)
        destroy_mono(p->p[i]);
    free(p->p);
    free(p);
}

mono *
new_mono(int w, int idx)
{
    mono *r;

    r = malloc(sizeof(*r));
    if (r == NULL)
        exit(-1);
    r->w = w;
    r->v = malloc(2 * w * sizeof(*r->v));
    if (r->v == NULL)
        exit(-1);
    for (int i = 0 ; i < 2 * w ; i++)
    {
        r->v[i] = malloc(4096);
        if (r->v[i] == NULL)
            exit(-1);
        r->v[i][0] = 0;
    }

    return r;
}

poli *
new_poli(int nvars, int w)
{
    poli *p;

    p = malloc(sizeof(*p));
    if (p == NULL)
        exit(-1);

    p->nvars = nvars++;
    p->p = malloc(((nvars + 1) * nvars * sizeof(*p->p)) / 2);
    if (p->p == NULL)
        exit(-1);
    nvars -= 1;

    for (int i = 0 ; i < nvars ; i++)
    {
        for (int j = 0 ; j <= i ; j++)
            p->p[pos(i, j)] = new_mono(w, i);
    }
   return p;
}

void
create_table(int w)
{
    table_red = malloc(2 * w * sizeof(*table_red));
    if (table_red == NULL)
        exit(-1);
    for (int i = 0 ; i < 2 * w ; i++)
        table_red[i] = mod((1 << i), w);
}

int **
read_input(int *npols, int *nvars, int *w, int **enc)
{
    int i, j;
    int **coefs;
    int nv;
    int np;

    *npols = 1;
    *nvars = 1;
    nv = *nvars + 1;
    np = *npols;

    enc[0] = malloc(sizeof(**enc) * np);
    if (enc[0] == NULL)
        exit(-1);
    for (i = 0 ; i < np ; i++)
        enc[0][i] = 0;

    coefs = malloc(sizeof(*coefs) * np);
    if (coefs == NULL)
        exit(-1);

    for (i = 0 ; i < np ; i++)
    {
        coefs[i] =  malloc(((nv + 1) * nv) / 2 * sizeof(**coefs));
        if (coefs[i] == NULL)
            exit(-1);
        for (j = 0 ; j < ((nv + 1) * nv) / 2 ; j++)
            coefs[i][j] = 0;
    }

    return coefs;
}


int main(int argc, char ** argv)
{
    int nvars;
    int npols;
    int i;
    int w;
    int *enc;
    int **coefs;
    int k;
    poli **p;

    w = 2;
    coefs = read_input(&npols, &nvars, &w, &enc);;

    create_table(w);
    npols = 1;
    p = malloc(npols * sizeof(*p));
    for (k = 0 ; k < npols ; k++) {
        p[k] = new_poli(nvars, w);
    }
    for (k = 0 ; k < npols ; k++)
        destroy_poli(p[k]);
    free(p);

    for (i = 0 ; i < npols ; i++)
        free(coefs[i]);
    free(coefs);
    free(enc);

    return 0;
}