【问题标题】:Error: Deallocating a 2D array错误:重新分配二维数组
【发布时间】:2014-01-14 19:04:57
【问题描述】:

我正在开发一个程序,其中一项任务是从文本文件中读取点(x、y 和 z),然后将它们存储在一个数组中。现在文本文件可能包含 10^2 甚至 10^6 点,具体取决于用户选择的文本文件。因此我定义了一个动态数组。

为了分配一个动态二维数组,我写了如下,它工作正常:

const int array_size = 100000;
float** array = new float* [array_size]; 
for(int i = 0; i < array_size; ++i){
    ary[i] = new float[2]; // 0,1,2 being the columns for x,y,z co-ordinates
}

将点保存到数组中后,我编写以下内容来释放未分配的内存:

for (int i = 0; i < array_size; i++){
    delete [] array[i];
}

delete [] array;

然后我的程序停止工作并显示“Project.exe 停止工作”。

如果我不取消分配,程序就可以正常工作。

【问题讨论】:

  • 您有什么令人信服的理由不使用std::arraystd::vector
  • 同样,为什么不创建一个包含 3 个浮点数的 struct 数组?
  • 你有一个错字ary[i] = new float[2]; ary => 数组
  • 这里写的代码没问题,为什么不贴真实的呢?
  • @adrin 在正确的轨道上。如果您认为可以将 3 个值 (0,1,2) 分配给 2 的数组,那么您就是在破坏内存。这可能是导致您的 delete [] 失败的原因。我假设一次迭代总是成功的。

标签: c++ arrays memory-management


【解决方案1】:

在您的评论中您说0,1,2 being the columns for x,y,z co-ordinates,如果是这种情况,您需要分配为float[3]。当您分配float[N] 的数组时,您分配了一块大小为N * sizeof(float) 的内存,并且您将在数组中将它们从1 索引到N - 1。因此,如果您需要索引0,1,2,则需要分配大小为3 * sizeof(float) 的内存,这使其成为float[3]

除此之外,我可以编译和运行代码而不会出错。如果您修复它但仍然出现错误,则可能是您的编译器问题。然后尝试将100000 减少到一个较小的数字,然后重试。

【讨论】:

  • 不要认为编译器可能是这里的问题。
  • 我同意在这种情况下你可以依赖编译器,但我怀疑这里的编译器是 Turbo C :D
  • @adrin 我使用 Dev C++ 作为 IDE,使用的编译器是 TDM-GCC 4.7.1。
  • 那么你发现问题了吗?
  • @adrin 你能告诉我为什么要使用 float[3] 而不是 float[2] 吗?抱歉,但我是 C++ 新手,之前曾在 Matlab 中编程。
【解决方案2】:

您是说您正在尝试实现一个动态数组,这就是std::vector 所做的,我强烈建议您使用它。这样,您就可以使用标准库中经过充分测试的东西,并且基本上不会因为尝试推出自己的std::vector 版本而遇到问题。此外,这种方法可以更好地包装内存,因为它使用 RAII,它利用该语言解决了许多内存管理问题。这还有其他好处,比如让您的代码更加安全。

此外,如果您要存储 x、y、z 坐标,请考虑使用结构或元组,我认为这会大大提高可读性。您也可以 typedef 坐标类型。像std::vector&lt; coord_t &gt; 这样的东西对我来说更具可读性。

【讨论】:

  • 但我在某处读到,为了增加向量的大小,值被推到向量的后面,它需要额外的处理。
  • 如果你事先知道数组中有多少个元素,你可以使用std::vectors reserve成员函数来预先分配大小。如果你想要一个动态数组,你会发现调整数组大小总是会有开销,这只是问题的本质。如果数组总是相同的大小,那么你可以使用std::array
【解决方案3】:

(非常感谢您的建议!)

最后我使用向量来解决上述问题,原因如下:

1.与数组不同(当然不是数组对象),我不需要手动释放未分配的内存。

2.vector类下定义了很多内置方法

  1. 向量大小可以在后期扩展

以下是我如何使用 2D Vector 存储点(x,y,z 坐标)

初始化(分配内存)一个二维向量:

          vector<vector<float>> array (1000, vector<float> array (3)); 

其中1000是行数,3是列数

一旦声明,值可以简单地传递为:

                      array[i][j] = some value;

另外,在后期我声明了接受向量参数并返回向量的函数:

          vector <vector <float>> function_name ( vector <vector <float>>);

   vector <vector <float>> function_name ( vector <vector <float>> input_vector_name)

   {

    return output_vector_name_created_inside_function

   }

注意:此方法在返回时会创建一个vector的副本,使用指针通过引用返回。即使当我通过引用返回向量时我的不工作:(

【讨论】:

    【解决方案4】:

    对于多数组,我建议使用boost::multi_array。 示例:

    typedef boost::multi_array<double, 3> array_type;
    array_type A(boost::extents[3][4][2]);
    A[0][0][0] = 3.14;
    

    【讨论】:

      猜你喜欢
      • 2021-10-11
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多