0

我正在编写 A* 代码,并且在尝试访问 int** 矩阵时遇到了一个奇怪的“分段错误”问题。

这里是矩阵示例的代码。当我尝试绘制第一个 cout 时,我得到了分段错误 11。

#include <iostream>

using namespace std;

int main(int argc, char** argv)
{
    int** matriz;

    matriz = (int**) malloc(10 * sizeof(int));

    // Defino una matriz de 10x12
    for (int i=0; i<10; i++)
    {
        matriz[i] = (int*) malloc(12 * sizeof(int));

        for (int j=0; j < 12; j++)
        {
            if( i == 11 && j == 5)
                matriz[i][j] = 13;
            else if( i == 10 && j == 7)
                matriz[i][j] = 5;
            else if( i == 3 && j == 11)
                matriz[i][j] = 4;
            else
                matriz[i][j] = 0;
        }
    }

    // Imprimo valores de prueba para comprobar que todos son accesible y que no encuentro un 'Segmentation Fault'
    cout << "Valor en (11, 5) --> " << matriz[11][5] << endl;
    cout << "Valor en (10, 7) --> " << matriz[10][7] << endl;
    cout << "Valor normal 0 en (4, 4) --> " << matriz[4][4] << endl;
    cout << "Valor en (3, 11) --> " << matriz[3][11] << endl;

    return 0;
}

有人可以告诉我做错了什么。我不明白为什么我可以绘制坐标值,例如 (4,4) 和 (3,11),但不能绘制靠近矩阵边界的 (11, 5) 或 (10,7) 坐标值。

提前致谢。

4

2 回答 2

3

首先,您可以阅读Why pointer to pointer and vector of vector is bad for simple matrixs。您需要输入密码“p2pbad”(不带“”)。

这条线

cout << "Valor en (11, 5) --> " << matriz[11][5] << endl;

将尝试访问一个不存在的元素,因为您的矩阵只有 10 行,但您想从第 11 行获取数据 -> 分段错误。出于同样的原因,条件

if( i == 11 && j == 5)

没有意义。我永远不会是 11 岁i == 10,在下一个条件下也不会是真的i<10

为通用矩阵处理编写非常好的代码是一项艰巨的任务,但您可能需要付出一些努力才能编写一个简单/基本的模板化矩阵类。

使用 std::allocator 的基本示例如下

template <typename _T>
class basic_matrix
{
public:
  typedef basic_matrix<_T>                this_type;
  typedef ::std::allocator<_T>            alloc;
  typedef typename alloc::value_type      value;
  typedef typename alloc::pointer         ptr;
  typedef typename alloc::const_pointer   const_ptr;
  typedef typename alloc::reference       ref;
  typedef typename alloc::const_reference const_ref;
  typedef typename alloc::size_type       size;
  typedef typename alloc::difference_type diff;
  typedef _T&&                            r_ref;

  basic_matrix (void) 
    : _data(nullptr), _x(0U), _y(0U)
  {
  }

  basic_matrix (size const & x, size const & y) 
    : _data(nullptr), _x(0U), _y(0U)
  {
    resize(x,y);
  }

  ~basic_matrix (void)
  {
    if (!empty()) clear();
  }

  void resize (size const &x, size const &y)
  {
    if (x == 0 && y == 0)
    {
      clear();
    }
    else
    {
      ptr new_location = _Allocate(x*y);
      if (!empty())
      { // old data existent -> copy it
        try 
        {
          size const N = min(x, _x), M = min(y, _y);
          for (size i=0; i<N; ++i)
          {
            for (size j=0; j<M; ++j)
            {
              *(new_location + i*y + j) = *(_data + i*_y + j);
            }
          }
        }
        catch (...)
        {
          _Deallocate(new_location, x*y);
          clear();
          throw;
        }
      }
      _data = new_location;
      _x = x;
      _y = y;
    }
  }

  ref operator() (size const &x, size const &y)
  {
    if (x >= _x || y >= _y) throw std::exception("OUT OF RANGE");
    return *(_data + x*_y + y);
  }

  const_ref operator() (size const &x, size const &y) const
  {
    if (x >= _x || y >= _y) throw std::exception("OUT OF RANGE");
    return *(_data + x*_y + y);
  }

  bool empty (void) const
  {
    return (_data == nullptr);
  }

  void clear (void)
  {
    _Deallocate(_data, _x*_y);
    _data = nullptr;
    _x = 0U;
    _y = 0U;
  }

protected:

  ptr _data;
  size _x, _y;
  alloc _allocator;

  ptr _Allocate (size const &num)
  {
    ptr new_location;
    try 
    {
      new_location = _allocator.allocate(num);
    }
    catch (...)
    {
      clear();
      throw;
    }
    return new_location;
  }

  void _Deallocate (ptr location, size const &num)
  {
    _allocator.deallocate(location, num);
  }

};

您将需要添加一个复制构造函数和一个赋值运算符以及其他一些东西......无论您希望矩阵接口的行为如何......

这可以使用如下代码工作:

int main (void)
{

  basic_matrix<int> matriz(10, 12);

    // Defino una matriz de 10x12
    for (int i=0; i<10; i++)
    {
        for (int j=0; j < 12; j++)
        {
            if( i == 9 && j == 7)
                matriz(i,j) = 5;
            else if( i == 3 && j == 11)
                matriz(i,j) = 4;
            else
                matriz(i,j) = 0;
        }
    }
    cout << "Valor en (10, 7) --> " << matriz(9,7) << endl;
    cout << "Valor normal 0 en (4, 4) --> " << matriz(4,4) << endl;
    cout << "Valor en (3, 11) --> " << matriz(3,11) << endl;
    return 0;
}

它打印:

Valor en (10, 7) --> 5
Valor normal 0 en (4, 4) --> 0
Valor en (3, 11) --> 4
于 2013-05-12T18:19:49.427 回答
2

如果您使用 C++(或更好的C++11,例如使用最近的 GCC -4.7 或更好的编译器 g++ -std=gnu++11 -Wall),您可以使用std::array(或std::vector至少)。

你至少应该编码

  matriz = (int**) malloc(10 * sizeof(int*));
  if (!matriz) { perror("malloc matriz"); exit(EXIT_FAILURE); };

(在我的 Linux/Debian/x86-64 机器上,sizeof(int)是 4,但是sizeof(int*)是 8)

因为matriz, eg的每个单独元素matriz[3]都是一个指针。

我宁愿建议在 C++11 中使用std::array和编码

  auto matriz = new std::array<std::array<int,12>,10>();

#include <array>

于 2013-05-12T17:29:46.953 回答