首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C: free()无效指针;不更改地址

C: free()无效指针;不更改地址
EN

Stack Overflow用户
提问于 2015-06-21 15:49:00
回答 1查看 238关注 0票数 0

我使用的是C(不是C++),并得到了以下错误:

Error in './c_rk4': free(): invalid pointer: 0x0000000000a911c0

我能够将错误追溯到行(1)和(2)。如果我注释掉标记的行,则不会出现(1)中的错误。所有其他free()用法都不会产生错误,如果我用free()注释掉所有行,程序就会按自己的意愿运行。

我用像printf("%p\n", y_n);这样的行检查y_n的地址在malloc()之后和free()之前是相同的(以及错误消息中的地址)。

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>

void odesolver_rk4 (void (*)(double, _Complex double *, _Complex double **),
            int, double,
            int, _Complex double *, _Complex double ***);
void testfunc (double, _Complex double *, _Complex double **);

int main (int argc, char *argv[argc]) {  
  const int t_num = 300;
  const int y_num = 2;

  _Complex double **y_res;
  y_res = malloc(t_num*sizeof(_Complex double *));
  for (int i = 0; i < t_num; i++)
    y_res[i] = malloc(y_num*sizeof(_Complex double));

  odesolver_rk4(testfunc, t_num, 20.0, y_num, (_Complex double []){1.0, 0.0}, &y_res);

  for (int i = 0; i < t_num; i++) {
    for (int j = 0; j <= y_num; j++) {
      printf("%f %f ", creal(y_res[i][j]), cimag(y_res[i][j]));
    }
    printf("\n");
  }

  for (int i = 0; i < t_num; i++)
    free(y_res[i]); // error (2)
  free(y_res);

  return 0;
}


void odesolver_rk4 (void (*func)(double, _Complex double *, _Complex double **),
            int t_num, double t_end,
            int y_num, _Complex double *y_start, _Complex double ***y_res) {
  double t_step = t_end/t_num;

  double t_n = 0;
  _Complex double *y_n, *y_A, *y_B, *y_C;
  _Complex double *dy_n, *dy_A, *dy_B, *dy_C;

  y_n = malloc(y_num*sizeof(_Complex double));
  y_A = malloc(y_num*sizeof(_Complex double));
  y_B = malloc(y_num*sizeof(_Complex double));
  y_C = malloc(y_num*sizeof(_Complex double));

  dy_n = malloc(y_num*sizeof(_Complex double));
  dy_A = malloc(y_num*sizeof(_Complex double));
  dy_B = malloc(y_num*sizeof(_Complex double));
  dy_C = malloc(y_num*sizeof(_Complex double));

  for (int j = 0; j < y_num; j++)
    y_n[j] = y_start[j];

  (*y_res)[0][0] = t_n;
  for (int j = 0; j < y_num; j++)
    (*y_res)[0][j + 1] = y_start[j];
  for (int i = 1; i < t_num; i++) {
    func(t_n, y_n, &dy_n);
    for (int j = 0; j < y_num; j++)
      y_A[j] = y_n[j] + dy_n[j]*t_step/2;

    func(t_n + t_step/2, y_A, &dy_A);
    for (int j = 0; j < y_num; j++)
      y_B[j] = y_n[j] + dy_A[j]*t_step/2;

    func(t_n + t_step/2, y_B, &dy_B);
    for (int j = 0; j < y_num; j++)
      y_C[j] = y_n[j] + dy_B[j]*t_step;

    func(t_n + t_step, y_C, &dy_C);
    for (int j = 0; j < y_num; j++) {
      y_n[j] += t_step/6*(dy_n[j] + 2*(dy_A[j] + dy_B[j]) + dy_C[j]);

      (*y_res)[i][0] = t_n;
      (*y_res)[i][j + 1] = y_n[j]; // something goes wrong here for (1)
    }

    t_n += t_step;
  }

  free(y_n); // error (1)
  free(y_A);
  free(y_B);
  free(y_C);

  free(dy_n);
  free(dy_A);
  free(dy_B);
  free(dy_C);
}

void testfunc (double t, _Complex double *y, _Complex double **dy) {
  (*dy)[0] = -y[1];
  (*dy)[1] = y[0];
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-06-21 15:59:32

问题在于这个循环:

for (int j = 0; j < y_num; j++)

这一行代码:

(*y_res)[i][j + 1] = y_n[j]

要么您的循环需要为j < y_num - 1,要么您的表达式应该使用[j]。否则,您将跨过y_res数组的末尾。当您这样做时,您将覆盖y_n分配的malloc头,这就是为什么free()稍后会抱怨它是一个无效指针的原因。

顺便说一句,伐研是找到这类问题的好工具。

http://valgrind.org

从评论中还推荐了AddressSanitizer:

http://clang.llvm.org/docs/AddressSanitizer.html

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30966373

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档