Ошибка сегментации - чтение массива инициализированных указателей - PullRequest
0 голосов
/ 23 октября 2018

Не могли бы вы помочь мне с небольшой проблемой?

У меня есть следующий класс;

class Link
{
  private:
    Demand *demand_[NUMBER_OF_CORES][NUMBER_OF_SLICES];

  public:
    Link()
    {
      for (int i = 0; i < NUMBER_OF_CORES; i++)
      {
        for (int j = 0; j < NUMBER_OF_SLICES; j++)
        {
          demand_[i][j] = NULL;
        }
      }
    }

    int virtualPut();
}

Будет проблема с массивом demand_.В конструкторе все хорошо, после инициализации я могу использовать if (demand_[i][j] == NULL).

Проблема начинается в virtualPut()

int Link::virtualPut()
{
  for (int i = 0; i < NUMBER_OF_CORES; i++)
  {
    for (int j = 0; j < NUMBER_OF_SLICES; j++)
    {
      std::cout << "We're in " << i << " " << j << " \n" << std::flush;

      if (demand_[i][j] == NULL)  //SEGMENTATION FAULT
      {
        std::cout << "EMPTY\n";
      }
    }
  }
}

А также - если я вызываю virtualPut() в конструкторе (простодля теста) работает нормально.

Но за пределами Link класса я использую.

void someFunction(Link *tab, int links)
{
  tab = new Link[links];

  tab[0].virtualPut();  //also just for test
}

В чем здесь может быть проблема?Я знаю, что могу использовать вектор, но это не поможет мне понять эту проблему с памятью.

Еще одна вещь - доктор Память говорит:

UNADDRESSABLE ACCESS: reading 0x0000000000000009-0x0000000000000011 8 byte(s)

Но почему?

EDIT! Проблема решена в комментариях, спасибо

1 Ответ

0 голосов
/ 23 октября 2018

Код, который вы нам показываете, в порядке .Я запускал его на своей стороне с огромными ценностями, а Сегфо нет.Вы объявили «Demand * array of array» в своем классе Link, и это допустимое объявление, память должна быть выделена.

Я подозреваю, что NUMBER_OF_CORES и / или NUMBER_OF_SLICES не делает 'В коде, в котором вы определяете класс Link, и в коде, в котором вы определили метод virtualPut, значение может быть одинаковым.

Что-то вроде:

#define NUMBER_OF_CORES 10
#define NUMBER_OF_SLICES 10
class Link
{
private:
    Demand *demand_[NUMBER_OF_CORES][NUMBER_OF_SLICES];
...
}

и

#define NUMBER_OF_CORES 5000
#define NUMBER_OF_SLICES 5000
int Link::virtualPut()
{
    for (int i = 0; i < NUMBER_OF_CORES; i++)
    {
        for (int j = 0; j < NUMBER_OF_SLICES; j++)
        {
        // here you will have buffer overflow
    ...
}

Что я хотел бы сделать:

  • использовать std :: vector
  • , вероятно, использовать массив из одной записи и обернуть его
  • не использовать #define, это грязно
  • не использовать массивы, это приводит к переполнению буфера

Это будет примерно так:

class Link
{
private:
    std::vector<Demand*> demand_;
    const int NUMBER_OF_CORES = 10;
    const int NUMBER_OF_SLICES = 50;
private:
    int getIdx(int i, int j)
    {
        return i*NUMBER_OF_SLICES + j;
    }
public:
    Link()
    {
        demand_.resize(NUMBER_OF_CORES * NUMBER_OF_SLICES);
        for (int i = 0; i < NUMBER_OF_CORES; i++)
        {
            for (int j = 0; j < NUMBER_OF_SLICES; j++)
            {
                demand_[getIdx(i,j)] = NULL;
            }
        }
    }
    int virtualPut();
};

Примечание: кроме того, вы показали нам virtualPut (), который должен возвращать int, но не возвращает.

...