简体   繁体   English

制作第二维是常数的动态二维数组是愚蠢的吗?

[英]Is it dumb to make a dynamic 2d array where the second dimension is a constant?

I am trying to make an array with a variable number of rows, but it will always have 4 columns.我正在尝试创建一个行数可变的数组,但它总是有 4 列。 Is doing something like:正在做类似的事情:

int** numGrades = new int* [num_exams];
for (int i = 0; i < num_exams; ++i)
{
    numGrades[i] = new int[4];
}

a good way to do this?这样做的好方法吗? I feel like there's an easier way, but I can't think of one.我觉得有一种更简单的方法,但我想不出一个。 Also, the array keeps giving me memory leaks so I'm wondering if that is because I'm doing something I shouldn't be.此外,该数组不断给我内存泄漏,所以我想知道这是否是因为我在做我不应该做的事情。 Vectors are banned for this program fyi.仅供参考,该程序禁止使用载体。

You could make an array of rows.你可以制作一个行数组。

struct Row{
   int values[4];
};

Row* numGrades = new Row[num_exams];

You could skip the for loop:您可以跳过 for 循环:

int* numGrades = new int[num_exams*4];
int firstElement = numGrades[x];
int secondElement = numGrades[x+1];
int thirdElement = numGrades[x+2];
int fourthElement = numGrades[x+3];

By skipping the for loop you gain this:通过跳过 for 循环,您可以获得:

  1. You don't have to have a for-loop for freeing the memory:您不必使用 for 循环来释放内存:

    delete[] numGrades;删除[] numGrades;

  2. The heap does not fragment so much because you don't call "new" so many times.堆没有那么多碎片,因为您不会多次调用“新”。

BUT it all depends what you are using it for.但这一切都取决于您使用它的目的。 In modern C++ is not such a good idea to use dynamic but make a struct in a std::vector.在现代 C++ 中,使用动态但在 std::vector 中创建结构并不是一个好主意。

Maybe you can try this.也许你可以试试这个。

typedef int row[4];
//or
using row = int[4];

row *numGrades = new row[num_exams];

Allocating some number of arrays of fixed size is fine and advantageous in many cases.在许多情况下,分配一定数量的固定大小的数组是好的和有利的。

In addition to a struct (which is a very good option), another option is to declare a Pointer-To-Array of a fixed number of elements.除了struct (这是一个很好的选择)之外,另一种选择是声明一个包含固定数量元素的Pointer-To-Array The benefit there is you have a Single-Allocation and Single-Free for the block of memory.这样做的好处是您可以为内存块提供单一分配单一空闲 (as you do with an array of struct ) If you need to grow the block of memory (with a -- declare bigger block, copy existing to bigger, delete existing reallocation), it simplifies the process. (就像使用struct 数组一样)如果您需要增加内存块(使用 -- 声明更大的块,将现有复制到更大,删除现有重新分配),它会简化过程。 In your case:在你的情况下:

 int (*numGrades)[4] = new int[num_exams][4];

Which will allocate num_exams number of arrays of 4 int all at once.这将一次分配num_exams数量的 4 个int数组。 That provides the benefit of a single delete[] numGrades;这提供了单个delete[] numGrades; when you are done with the memory.当你完成记忆时。

A short example that uses a std::istringstream to hold example values to be read into a block of memory containing fixes size arrays could be:使用std::istringstream保存示例值以读取到包含修复大小数组的内存块的简短示例可能是:

#include <iostream>
#include <sstream>

int main (void) {
    
    std::istringstream iss { "1 2 3 4 5 6 7 8 9" };
    
    int npoints = 3,
        (*points)[3] = new int[npoints][3],
        n = 0;
    
    while (n < 3 && iss >> points[n][0] >> points[n][1] >> points[n][2])
        n++;
    
    for (int i = 0; i < n; i++)
        std::cout << points[i][0] << "  " << points[i][1] << "  " << points[i][2] << '\n';
    
    delete[] points;
}

( note: you should avoid using new and delete in favor of a container such as std::vector if this is for other than educational purposes) 注意:如果不是出于教育目的,您应该避免使用newdelete来支持诸如std::vector之类的容器)

Example Use/Output示例使用/输出

$ ./bin/newptr2array3
1  2  3
4  5  6
7  8  9

Worth noting, the benefit of the struct is that it will allow you to overload >> and << with std::istream and std::ostream to provide a convenient functions to read and write the data you need.值得注意的是, struct的好处是它允许您使用std::istreamstd::ostream重载>><<以提供方便的函数来读取和写入您需要的数据。

So either way, a Pointer-to-Array of fixed elements, or creating a struct and then an Array of struct is perfectly fine.所以无论哪种方式,一个指针到阵列固定元件,或创建一个struct ,然后数组struct是完全没有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM