繁体   English   中英

在双数组的 calloc 上写入大小为 8 的无效

[英]Invalid write of size 8 on calloc of double array

我不想在这里问它,但我几乎别无选择。

我有一个矩阵结构

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

typedef struct Matrix{
  double *mat;
  int rows;
  int columns;
} Matrix;

我这样初始化

Matrix* init_Matrix(int rows, int columns) {
  Matrix *matrix = (Matrix*) malloc(sizeof(Matrix));

  matrix->rows = rows;
  matrix->columns = columns;
  matrix->mat = (double*) calloc(rows*columns, sizeof(double));

  return matrix;
}

但是,当我将它作为更大代码的一部分运行时,它最终给出了

malloc(): corrupted top size
Aborted (core dumped)

该错误不是系统性的,发生在代码中的第二次初始化时。 这促使我用valgrind测试它,它给出了以下输出

==19211== Invalid write of size 8
==19211==    at 0x1096DF: odometer(Robot*, double, double, double) (main.cc:41)
==19211==    by 0x109B6F: main (main.cc:82)
==19211==  Address 0x4dcbe68 is 0 bytes after a block of size 72 alloc'd
==19211==    at 0x483CD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==19211==    by 0x109C33: init_Matrix(int, int) (matrix_gr7.cc:18)
==19211==    by 0x1095BD: odometer(Robot*, double, double, double) (main.cc:38)
==19211==    by 0x109B6F: main (main.cc:82)

calloc显然是问题所在,但我找不到我做错了什么。 有没有人有想法?

编辑:为错误再现matrix_gr7.h添加附加代码

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

typedef struct Matrix{
  double *mat;
  int rows;
  int columns;
} Matrix;

Matrix* init_Matrix(int rows, int columns);
void free_Matrix(Matrix *matrix);

Matrix* matrix_product(Matrix *a, Matrix *b);

Matrix* matrix_sum(Matrix *a, Matrix *b);

Matrix* matrix_transpose(Matrix *a);

void print_matrix(Matrix *a);

matrix_gr7.cc

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <math.h>
#include "matrix_gr7.h"


Matrix* init_Matrix(int rows, int columns) {
  Matrix *matrix = (Matrix*) malloc(sizeof(Matrix));

  matrix->rows = rows;
  matrix->columns = columns;
  matrix->mat = new double[rows*columns];

  return matrix;
}

void free_Matrix(Matrix *matrix) {
  if (matrix != NULL) {
    if (matrix->mat != NULL) {
      free(matrix->mat);
    }
    free(matrix);
  }
}

Matrix* matrix_product(Matrix *a, Matrix *b) {
  Matrix *c = init_Matrix(a->rows, b->columns);

  double temp;

  for (int i = 0; i < a->rows; i++) {
    for (int j = 0; j < b->columns; j++) {
      temp = 0;
      for (int k = 0; k < a->columns; k++) {
        temp += (a->mat[k+(i*a->columns)])*(b->mat[j+(k*b->columns)]);
      }
      c->mat[i*(c->columns) + j] = temp;
    }
  }
  return c;
}

Matrix* matrix_sum(Matrix *a, Matrix *b) {
  Matrix *c = init_Matrix(a->rows, a->columns);
  for (int i = 0; i < a->rows*a->columns; i++) {
    c->mat[i] = a->mat[i] + b->mat[i];
  }
  return c;
}

Matrix* matrix_transpose(Matrix *m) {
  Matrix *n = init_Matrix(m->columns, m->rows);
  for (int i = 0; i < m->rows; i++) {
    for (int j = 0; j < m->columns; j++) {
      n->mat[i + j*n->columns] = m->mat[j + i*m->columns];
    }
  }
  return n;
}

void print_matrix(Matrix* m) {
  for (int i = 0; i < m->rows*m->columns; i++) {
    printf("%f  ,", m->mat[i]);
    if ((i+1)%m->columns  == 0) {
      printf("\n");
    }
  }
}

robot.h

#include "matrix_gr7.h"

typedef struct Robot {
  double x;
  double y;
  double th;
  Matrix *Sig_p;
  double last_t_update;
} Robot;

Robot* init_Robot(double x, double y, double th);

void free_Robot(Robot* robot);

robot.cc

#include "robot.h"
#include "matrix_gr7.h"

Robot* init_Robot(double x, double y, double th) {
  Robot* robot = (Robot*) malloc(sizeof(Robot));
  robot->x = x;
  robot->y = y;
  robot->th = th;
  robot->last_t_update = 0;
  robot->Sig_p = init_Matrix(3, 3);

  return robot;
}

void free_Robot(Robot* robot) {
  free_Matrix(robot->Sig_p);
  free(robot);
}

main.cc

#include <stdio.h>
#include <math.h>
#include "matrix_gr7.h"
#include "robot.h"

void odometer(Robot* cvs, double w_r, double w_l, double t) {
  Matrix *grad_p_f = init_Matrix(3, 3);
  grad_p_f->mat[7] = 0; grad_p_f->mat[8] = 0; grad_p_f->mat[9] = 1;

  Matrix *grad_p_f_T = matrix_transpose(grad_p_f);

  Matrix *grad_rl_f = init_Matrix(3, 2);
  grad_rl_f->mat[5] = 1.0/0.225;
  grad_rl_f->mat[6] = -1.0/0.225;

  Matrix *grad_rl_f_T = matrix_transpose(grad_rl_f);
  Matrix *Sig_rl = init_Matrix(2,2);

  Matrix *temp1 = matrix_product(grad_p_f, cvs->Sig_p);
  Matrix *temp2 = matrix_product(temp1, grad_p_f_T);
  Matrix *temp3 = matrix_product(grad_rl_f, Sig_rl);
  Matrix *temp4 = matrix_product(temp4, grad_rl_f_T);

  free_Matrix(cvs->Sig_p);
  cvs->Sig_p = matrix_sum(temp2, temp4);

  free_Matrix(grad_p_f); free_Matrix(grad_p_f_T); free_Matrix(Sig_rl);
  free_Matrix(grad_rl_f); free_Matrix(grad_rl_f_T);
  free_Matrix(temp1); free_Matrix(temp2);
  free_Matrix(temp3); free_Matrix(temp4);
  cvs->last_t_update = t;
}

int main() {
  Robot* robot = init_Robot(0, 0, 0);

  odometer(robot, 1, 1, 1);
  matrix_transpose(robot->Sig_p);

  free_Robot(robot);

  return 0;
}

The program fails at the `Matrix *grad_p_f_T = matrix_transpose(grad_p_f);` line but `valgrind` shows memory issues way before that.

写入grad_p_f->mat[9] = 1; 分配数组后不久就出界了。 您的数组是 3*3=9 个元素,索引从 0 开始(因此有效下标为 0..8 包括在内)。

此写入超出了calloc调用分配的内存末尾,并由 valgrind 报告。

我认为你所有的下标都是一个。

暂无
暂无

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

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