Ошибка сегментации в тестовом коде каскадных указателей структур - PullRequest
1 голос
/ 05 октября 2011

Следующий фиктивный тестовый код дает ошибку сегментации в конце выполнения (чтобы быть более точным в main при возврате 0). Я задавался вопросом причина этого поведения. Будет ли это потому, что он не может освободить фиктивную переменную? Я использую g ++ 4.4 без флагов оптимизации для тестов.

#include <vector>
#include <boost/multi_array.hpp>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using std::vector;

typedef boost::multi_array<float, 1> DVec;

class Point{
  public:
    int x, y;
    double *dist;
    DVec dir;
};

struct another_struct {
  vector <Point *>c;
};

struct in_foo{
  vector <another_struct *>aVec;
  char *aname;
  float b;
};

struct foo {
  DVec b;
  vector<in_foo *> mVec;
};

int main(){

  DVec c(boost::extents[4]);
  foo **dummy = (foo **) calloc(4, sizeof(*dummy));
  vector <in_foo *>test_var(5);

  for(int i =0; i < 6; i++){
    test_var[i] = (in_foo *) malloc(sizeof(in_foo));
    memset(test_var[i], 0, sizeof(*test_var[i]));
    test_var[i]->aname = "42!\n";
    test_var[i]->b = (float) i;
  }

  for (int i = 0 ; i < 4; i++) {
    dummy[i] = (foo *) malloc(sizeof(*dummy[i]));
    (dummy[i]->b).resize(boost::extents[2]);
    (dummy[i]->mVec) = test_var;
  }

  for (int i = 0 ; i < 4; i++) {
    for(int j = 0; j < 5; j++){
      (dummy[i]->mVec[j]->aVec).resize(5);
      for (int n = 0; n < 6; n++) {
        dummy[i]->mVec[j]->aVec[n] = new another_struct();
        (dummy[i]->mVec[j]->aVec[n])->c.resize(3);
        for (int m = 0; m < 4; m++) {
          (dummy[i]->mVec[j]->aVec[n]->c[m]) = new Point();
          (dummy[i]->mVec[j]->aVec[n]->c[m])->x = 100 * n;
          (dummy[i]->mVec[j]->aVec[n]->c[m])->y = 11000 * m;
          (dummy[i]->mVec[j]->aVec[n]->c[m])->dist = new double[2];
          (dummy[i]->mVec[j]->aVec[n]->c[m])->dist[0] =  11200.123;
          (dummy[i]->mVec[j]->aVec[n]->c[m])->dist[1] =  66503.131;
          printf("x: %d, y: %d, dist 0: %f, dist 1: %f \n", (dummy[i]->mVec[j]->aVec[n]->c[m])->x, (dummy[i]->mVec[j]->aVec[n]->c[m])->y, (dummy[i]->mVec[j]->aVec[n]->c[m])->dist[0], (dummy[i]->mVec[j]->aVec[n]->c[m])->dist[1]);
        }
      }
      printf("b: %f aname: %s \n", dummy[i]->mVec[j]->b, dummy[i]->mVec[j]->aname);
    }
  }

  if (NULL != dummy) {
    for(int i = 0; i < 4; i++)
    {
      free(dummy[i]);
    }
    free(dummy);
  }
  return 0;
}

1 Ответ

2 голосов
/ 05 октября 2011

Нельзя использовать malloc или calloc для выделения памяти для класса или структуры, отличной от POD, например vector, foo, in_foo.Как только вы сделаете это, все ставки отключены, и любое поведение, отображаемое вашей программой, будет в пределах разумного.

Используйте new с умными указателями или, что еще лучше, используйте состав, если это возможно. Указатели с new.

...