通过指针或值修改动态2D数组行

时间:2014-06-03 14:18:33

标签: c++ arrays

请考虑以下代码:

#include <Windows.h>
#include <stdio.h>

void print2d(int** A,int Y,int X)
{
    for(int i=0;i<Y;i++)
    {
        for(int j=0;j<X;j++)
            printf("%d ", A[i][j]);
        printf("\n");
    }
}

int main()
{
    int Y=2;
    int X=4;
    int** tab2d=new int*[Y];
    for(int i=0;i<Y;i++)
    {
        tab2d[i]=new int[X];
        for(int j=0;j<X;j++)
            tab2d[i][j]=0;
    }

    int* row=new int[X];
        for(int i=0;i<X;i++)
        row[i]=i;

    int option=0;
    switch(option)
    {
    case 0:
        tab2d[Y-1]=row;

    case 1:
        for(int i=0;i<X;i++)
            tab2d[Y-1][i]=i;
    }

    print2d(tab2d,Y,X);
    free(tab2d);
    free(row);

    system("pause");
}

鉴于在实际代码中,2d数组会有很多迭代,对于case 0或case 1有什么优势吗?分配新的行指针似乎是一种更好的方法,但它不会在整个内存中分隔我的数组行吗?

3 个答案:

答案 0 :(得分:1)

这两种解决方案并不相同。

案例0: 此处,数组元素将更改为指向您已创建的新行(即初始化时分配的行)。这几乎肯定不是你因为a)它留下内存泄漏,因为你最初创建的数组元素永远不会被释放,另外当你删除时,tab2d指向的内存不再有效(一旦访问它将导致未定义的行为 - 最有可能是崩溃)。

案例1: 你期望它做什么。

另外我想你需要知道,一般来说你的最终删除不会删除指针在2D数组中引用的对象,只是删除数组本身。因此,即使在案例1中,您也会产生非常严重的内存泄漏。

答案 1 :(得分:1)

一些事情:

1)如果你的行都是相同数量的列,那么创建和销毁2d数组的一般方法是次优的。请参阅此处另一种方法的答案:

Delete 2D array C++

2)至于创建一个新行只是为了替换值 - 为什么要创建一个全新的行?为什么不必要地调用allocator(和deallocator来删除旧行)?为什么不直接更改2d数组的现有行中的值?

我可以看到你是否在运行时删除或向你的2d数组添加行,然后你就可以在创建行和销毁各行时合理。但是,如果你不改变二维数组的大小,只需更改二维数组中的值,就不要创建新行。

答案 2 :(得分:-1)

首先,不要一起使用new / delete和malloc / free。否则行为未定义。 其次,您的第3个声明不得缩进。 关于你的问题: 对于代码中的每个new / malloc,应该存在匹配的delete / free。 在选项0(甚至选项1)中,您将丢失对tab2d [Y-1]的引用,导致内存泄漏,并在删除'row'和'tab2d [Y-1]时结束时双删除虽然它们都指向相同的地址,但行为未定义。

在这里,你在选项0中所做的是不正确的,但是如果你做了你想要正确做的事情,并且根据情况,它可以更有效的方式。