【问题标题】:Invalid write/read of size 8大小为 8 的无效写入/读取
【发布时间】:2023-03-16 14:07:01
【问题描述】:

处理一些使用矩阵的 C 代码。我创建了一个 Matrix 结构,以便更容易快速有效地创建它的许多实例,但我不确定我的代码为什么会泄漏内存。目前我有以下代码:

    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

【问题讨论】:

  • 尝试使用-g 进行编译,这样valgrind 将向您显示发生这些访问的确切行...
  • 您的代码中没有矩阵(又名二维数组)。指针不是数组!如果您需要矩阵,请使用二维数组。并且一般不要投射malloc & friends 或void * 的结果。
  • 学习以下内存分配习语:T p = malloc(sizeof *p)T p = malloc(N * sizeof *p),其中T 是某种指针类型。 IE。 sizeof 下没有类型名,也没有转换 malloc 的结果。这将使您在未来避免此类错误。

标签: c valgrind


【解决方案1】:

线

    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?

【讨论】:

  • 将我的代码更改为“Matrix mat = (Matrix) malloc(sizeof(*Matrix))”时出现错误:'Matrix' Matrix mat = (Matrix) malloc(sizeof( *矩阵));
  • sizeof(*Matrix) 无效。 Matrix 是一种类型。您不能“尊重”C 中的类型。您不能通过将* 运算符应用于指针类型将指针类型转换为pontee 类型。 C 中没有这样的功能,但乍一看它可能是合乎逻辑的。
  • 您的答案的第二部分也存在拼写错误。由于您将Matrix 重新定义为结构类型(而不是原始指针类型),因此应用于malloc 结果的转换应该是(Matrix *),而不是(Matrix)。当然,一个更好的主意是根本不施放。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多