2016-11-11 60 views
2

处理一些使用矩阵的C代码。我已经创建了一个Matrix结构,以便更快更高效地创建它的许多实例,但我不确定为什么我的代码正在泄漏内存。目前我有以下代码:无效的写入/读取大小为8

typedef struct 
    { 
    size_t rows; 
    size_t cols; 
    double ** value; 
      } 
    *Matrix; 


Matrix matCreate(size_t rows, size_t cols) 
{ 
     if(rows<=0 || cols<=0) 
     { 
       return NULL; 
     } 
     Matrix mat = (Matrix) malloc(sizeof(Matrix)); 
     mat->rows = rows; 
     mat->cols = cols; 
     mat->value = (double **) malloc(rows*sizeof(double*)); 
     for (int i=0; i< rows;i++) 
     { 
       mat->value[i] = (double *) malloc(cols * sizeof(double)); 
       for(int j=0; j< cols;j++) 
       { 
         mat->value[i][j] = 0; 

         if(rows == cols && i==j) 
         { 
           mat->value[i][j] = 1; 
         } 
       } 

     } 
     return mat; 
} 

而且我运行valgrind后出现以下内存泄漏。运行代码时,它完全无错地编译,并仍然输出正确的输出。

==23609== Invalid write of size 8 
==23609== at 0x400800: matCreate 
==23609== by 0x4010E2: main 
==23609== Address 0x5203048 is 0 bytes after a block of size 8 alloc'd 
==23609== at 0x4C2DB8F: malloc 
==23609== by 0x4007E8: matCreate 
==23609== by 0x4010E2: main 
==23609== 
==23609== Invalid write of size 8 
==23609== at 0x40081B: matCreate 
==23609== by 0x4010E2: main 
==23609== Address 0x5203050 is 8 bytes after a block of size 8 alloc'd 
==23609== at 0x4C2DB8F: 
==23609== by 0x4007E8: matCreate 
==23609== by 0x4010E2: main 
==23609== 
==23609== Invalid read of size 8 
==23609== at 0x40082F: matCreate 
==23609== by 0x4010E2: main 
==23609== Address 0x5203050 is 8 bytes after a block of size 8 alloc'd 
==23609== at 0x4C2DB8F: malloc 
==23609== by 0x4007E8: matCreate 
==23609== by 0x4010E2: main 
+0

尝试使用'-g'进行编译,所以'valgrind'会向您显示访问发生的确切路线...... – BadZen

+0

您的代码中没有矩阵(又名二维数组)。指针不是数组!如果你需要矩阵使用二维数组。一般不要将'malloc'和朋友或'void *'结果。 – Olaf

+0

学习以下内存分配习语:'T p = malloc(sizeof * p)'或'T p = malloc(N * sizeof * p)',其中'T'是一些指针类型。即'sizeof'下没有类型名称,也没有投射'malloc'的结果。这样可以避免你在这样的失误中遇到困难。 – AnT

回答

3

线

Matrix mat = (Matrix) malloc(sizeof(Matrix)); 

不好。它没有分配足够的内存。因此,您的程序具有未定义的行为。

size(Memory)评估指针的大小,而不是struct的大小。

它需要:

Matrix mat = malloc(sizeof(*mat)); 

定义Matrix这确实是一个指针没有良好的编码习惯。这会导致混乱。我建议将其定义为:

typedef struct 
{ 
    size_t rows; 
    size_t cols; 
    double ** value; 
} Matrix; 

,然后使用:

Matrix* matCreate(size_t rows, size_t cols) { ... } 

... 

Matrix* mat = malloc(sizeof(*mat)); 

Do I cast the result of malloc?

+0

当我的代码更改为“矩阵mat =(矩阵)malloc(sizeof(*矩阵))”我得到错误:预计表达矩阵之前矩阵mat =(矩阵)malloc(sizeof(*矩阵)); – WasabiCannon

+1

'sizeof(* Matrix)'无效。 “矩阵”是一种类型。你不能在C中“推”“一个类型。你不能通过应用'*'运算符来将指针类型转换为pontee类型。 C中没有这样的功能,但它可能看起来很合逻辑。 – AnT

+0

你的答案的第二部分也有错别字。由于您将'Matrix'重新定义为结构类型(而不是原始指针类型),因此您应用于'malloc'结果的类型应该是'(Matrix *)',而不是'(Matrix)'。当然,一个更好的主意根本不会被抛弃。 – AnT

0

变化

Matrix mat = (Matrix) malloc(sizeof(Matrix)); 

Matrix mat = (Matrix) malloc(sizeof(*Matrix)); 

deference the pointer。现在,您正在为您的矩阵分配足够的空间用于指针,而不是对象本身。

+0

'sizeof(* Matrix)'无效。 “矩阵”是一种类型,而不是指针。你不能“尊重”C中的一个类型。 – AnT