2015-12-04 68 views
0

我想了解为什么使用valgrind后面的代码是错误的。这个问题显然是在功能destroy_poli,我这样说是因为当我发表意见的主要功能Valgrind块丢失

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

的这一部分,我得到0误差与的valgrind。请你能帮助我们了解我的错误在哪里吗?

#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== 
+0

它可以让你在那里这些块所分配的行号(以及调用该函数的函数等)。所以看看哪些块被分配到这些行上,然后看看它们被认为是被释放的位置(显然没有被释放),这就是你的问题。 – immibis

+2

1)不要将'malloc'和朋友的结果放在C中。2)TL; DR提供[mcve]。 – Olaf

+0

很难看出问题在哪里(*你已经使用了很多'malloc()',你甚至没有检查过'malloc()'错误,并且你使用了'malloc()'where有时候并不需要,你也用'malloc()'作为一个全局变量,这是一个坏主意,全局变量本身是一个坏主意*),但最重要的是用'-g'编译让valgrind显示行号。而且,你的代码将声明和语句混合在一起(*它也是一团糟*),所以很难看到给定变量的上下文/作用域。 –

回答

2

你缺少在destroy_poli()free(p)free(m)destroy_mono()。我能够确定通过编译-g并使用valgrind来检查线路nunmber哪里泄漏的指针被分配跟踪它导致我发现问题。我做的另一件事是在某种程度上,它可以进行调试和维护编写的代码,请检查这一点,并告诉我它是否值得努力

#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; 
} 
+0

谢谢!没关系! – Juan

+0

@Juan,我发布了答案,因为尽管代码混乱了,但你确实写了一个非常好的程序。这是非常不安全的,你应该经常检查错误。 –