Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在第二个维度是常量的情况下创建动态2d数组是否愚蠢?_C++ - Fatal编程技术网

C++ 在第二个维度是常量的情况下创建动态2d数组是否愚蠢?

C++ 在第二个维度是常量的情况下创建动态2d数组是否愚蠢?,c++,C++,我试图创建一个行数可变的数组,但它总是有4列。正在做一些类似于: int** numGrades = new int* [num_exams]; for (int i = 0; i < num_exams; ++i) { numGrades[i] = new int[4]; } int**numGrades=newint*[num_检查]; 对于(int i=0;i < p>也许你可以试试这个。 typedef int row[4]; //or using row = int[4

我试图创建一个行数可变的数组,但它总是有4列。正在做一些类似于:

int** numGrades = new int* [num_exams];
for (int i = 0; i < num_exams; ++i)
{
    numGrades[i] = new int[4];
}
int**numGrades=newint*[num_检查];
对于(int i=0;i

这样做的好方法?我觉得有更简单的方法,但我想不出一个。此外,阵列不断给我内存泄漏,所以我想知道这是否是因为我正在做一些我不应该做的事情。此程序禁止使用矢量供参考。

您可以创建一个行数组

struct Row{
   int values[4];
};

Row* numGrades = new Row[num_exams];

您可以跳过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];
通过跳过for循环,您可以获得以下结果:

  • 您不必使用for循环来释放内存:

    删除[]个numGrades

  • 堆不会分割太多,因为您不会多次调用“new”


  • 但这完全取决于你用它做什么。在现代C++中,使用STEP不是一个好主意,而是在STD中构造一个::vector。< /p> < p>也许你可以试试这个。
    typedef int row[4];
    //or
    using row = int[4];
    
    row *numGrades = new row[num_exams];
    

    在许多情况下,分配一些固定大小的数组是很好的,也是很有利的

    除了
    struct
    (这是一个非常好的选项)之外,另一个选项是声明一个指向固定数量元素数组的指针。这样做的好处是,您可以对内存块进行单次分配和单次空闲。(就像处理结构数组一样)如果需要增加内存块(使用--declare biger block、copy existing to biger、delete existing reallocation),它可以简化过程。就你而言:

     int (*numGrades)[4] = new int[num_exams][4];
    
    它将一次分配4个数组的数量。提供单个
    delete[]numGrades的好处当您使用完内存时

    使用
    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;
    }
    

    值得注意的是,
    struct
    的好处是,它可以让你超载
    >
    ,并且
    你会用它做什么?这是我计算学生成绩的更大作业的一部分。这个特殊的数组将存储任何给定数量的考试的每个等级(a、B、C、D、F)的编号。答案-否。如果您处理的是总是有4个
    int
    ,那么您的分配应该是
    int(*numGrades)[4]=新的int[num_考试][4]
    为了提供单个分配和单个内存块释放(使重新分配更容易),我尝试这样分配它,但现在它不允许我将数组传递给任何函数。它说“int*类型的参数与int**类型不兼容”。声明它的方式是否使它不再是2d数组?这有什么实际的好处吗?我已经将其作为2d数组使用,但如果值得更改,我会这样做。@aons32是的,它将减少动态分配的需要。您不必担心
    num_考试
    分配,只需担心一次。如果不允许使用向量,这可能是最好的解决方案。这也可能修复奇怪的内存泄漏。明天我可能会尝试一下如果不是所有STL容器都被禁止,甚至
    新的int[4*num_检查]
    @aons32结构方法的另一个优点是:如果每一行代表一个学生的考试,那么您还可以向结构中添加函数并执行以下操作:
    for(const row&student:numGrades)student.calculateAverage(),或者,正如David C.Rankin所建议的,重载操作符>>,我宁愿使用向量,但我不允许这样做。跳过for循环又有什么意义呢?@aons32我解释了为什么跳过for循环是个好主意。
    
    $ ./bin/newptr2array3
    1  2  3
    4  5  6
    7  8  9