无法访问内存

时间:2013-09-19 14:25:48

标签: c gdb segmentation-fault

我遇到了段错误,当我调试它时,我收到以下消息:

无法访问内存0x806d128

我试图在那里设置一个观察点来监控地址,但gdb给我的响应是:

  

无法观看常数值'0x806d128'

然而,当我打印包含地址的指针时,它识别出我存储在那里的结构:

  

(正文*)0x806d128

根据gdb,addForce()发生了错误,这有点奇怪,因为init()

之前访问过该地址

以下是相关代码:

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

#define prec float

prec gdt = 0.0001;

typedef struct {
  float Fx, Fy, vx, vy, mass;
  int posX, posY;
} body;


void addForce(body* a, body* b){
  int xa=(*a).posX, ya=(*a).posY;
  int xb=(*b).posX, yb=(*b).posY;
  float F=(*a).mass * (*b).mass * gdt /(pow(xa-xb, 2)+pow(ya-yb, 2));
  float v=atan((ya-yb)/(xa-xb));
  float Fx=cos(v)/F, Fy=sin(v)/F;
  (*a).Fx+=Fx;
  (*a).Fy+=Fy;
  (*b).Fx-=Fx;
  (*b).Fy-=Fy;
}


int newRandInt(int bot, int top){
  return bot + (rand() % (top++));
}

prec newRand() 
{
    prec r = (prec)((double)rand()/(double)RAND_MAX);
    return r;
}


void init(int N, body* star){
  for(int i=0; i<N;i++){
    star[i].posX = newRandInt(0, 800);
    star[i].posY = newRandInt(0, 800);

    star[i].Fx = newRand();
    star[i].Fy = newRand();

    star[i].vx = newRand();
    star[i].vy = newRand();

    star[i].mass = newRand();
  }
}

int main(int argc, char* argv[]) {

    int N = 200;

body* stars = malloc(sizeof(body)*N);

init(N, stars);
for(int j1=0; j1<N; j1++){
  for(int j2=0; j2<N-1; j2++){
    if(j1!=j2){
      addForce(stars+sizeof(body)*j1, stars+sizeof(body)*j2);
    }
  }
}
return 0;

}

2 个答案:

答案 0 :(得分:0)

addForce的来电不符合您的要求:

addForce(stars+sizeof(body)*j1, stars+sizeof(body)*j2);

您不希望此sizeof(body)调用中的addForce表达式。你可能想要的电话是:

  addForce(stars+j1, stars+j2);

starsbody的数组,因此您可以使用

引用单个星标
body *p = &stars[i]

或只是

body *p = stars + i

这两个都有类型主体*

答案 1 :(得分:0)

在这一行:

addForce(stars+sizeof(body)*j1, stars+sizeof(body)*j2);

当你执行sizeof(body)时,它会以字节为单位计算结构大小,然后乘以j1。所以你有some_nr*j1 这个值是added到星星,它是指向身体的指针 指针算术评估some_nr*j1*sizeof(pointer to body) 你想要做的只是stars+j1,它将被正确评估为指向body的指针并添加到数组中 同样的事情发生在addForce的第二部分。

你错过的是使用指针算术,重新计算'+'运算符的第二个操作数以匹配指针的大小。