Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.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++ 使用新的For 2D数组重写此Malloc_C++_C_Multidimensional Array_Malloc_New Operator - Fatal编程技术网

C++ 使用新的For 2D数组重写此Malloc

C++ 使用新的For 2D数组重写此Malloc,c++,c,multidimensional-array,malloc,new-operator,C++,C,Multidimensional Array,Malloc,New Operator,经过一些尝试和错误,我找到了一种方法来malloc一个2D数组,这样它在内存中是连续的,相当于非动态情况 int numRows =2; int numCols = 4; int (*p)[numCols]; p = (int (*)[numCols]) malloc(sizeof(int)*numRows*numCols); 所以p现在基本上和我做int p[2][4]时一样,只是它在堆上而不是堆栈上 2个问题: 我需要调用free(p)来释放内存吗?没有循环 如何将其转换为使用new

经过一些尝试和错误,我找到了一种方法来malloc一个2D数组,这样它在内存中是连续的,相当于非动态情况

int numRows =2;
int numCols = 4;
int (*p)[numCols];
p    = (int (*)[numCols]) malloc(sizeof(int)*numRows*numCols);
所以p现在基本上和我做int p[2][4]时一样,只是它在堆上而不是堆栈上

2个问题:

  • 我需要调用free(p)来释放内存吗?没有循环
  • 如何将其转换为使用new而不是malloc
  • 我试过了

    p = new (int (*)[4])[2];
    
    但这就产生了错误:

    error: cannot convert int (**)[4] to int (*)[4] in assignment
    

    你不能在C++中这样做。你的代码> MalCube()/Cuth>代码完全有效C,但不是有效C++。而且它不能与
    new
    一起使用

    C++要求数组类型具有恒定大小,C允许数组类型具有动态大小。对于一维数组来说,只有一个例外,它可以用C++中的动态大小分配,但就是这样。在二维数组中,第二个大小必须在编译时已知

    <>这是C比C++更强大的一点。


    说服
    g++
    遵守这方面的标准需要一些时间,但是编译这个小程序

    #include <stdlib.h>
    
    int main(int argc, char** args) {
        int (*foo)[argc];
    }
    
    1) 是的,您可以直接调用
    free()

    但是,注意,您正在做(两个指向不同类型的指针,int和int[]具有相同地址),这可能会导致微妙的优化错误。而C++中使用<代码> MARROCKE()/COD>是非常糟糕的做法,NoNCORS应该是<代码> const 。p> < p > 2)在C++中这样做的方式是使用<代码> [][2 ] < /Cord>如果在编译时知道的大小:

         array<array<int, 4>,2> a;
    

    第一个维度也可以是可变的,但第二个维度必须是常量。但我鼓励您使用标准容器替代方案。

    这里有一个类模板,它使用一个
    std::vector
    来保存连续缓冲区,并使用大小感知代理对象逐维度访问数组元素:

    template<typename T>
    class TwoDArray {
    private:
        std::size_t n_rows;
        std::size_t n_cols;
        std::vector<T> buf;
    
    public:
        class OneDArrayProxy {
        private:
            T *rowptr;
            std::size_t colsize;
    
        public:
            OneDArrayProxy(const T *rp, std::size_t cs) : rowptr(const_cast<T *>(rp)), colsize(cs) {}
            T const &operator[](std::size_t index) const {
                return rowptr[index];
            }
    
            T &operator[](std::size_t index) {
                return rowptr[index];
            }
    
            std::size_t size() const { return colsize; }
        };
    
        TwoDArray(std::size_t rows, std::size_t cols) : n_rows(rows), n_cols(cols), buf(rows * cols) {}
        TwoDArray() : TwoDArray(0, 0) {}
    
        OneDArrayProxy operator[](std::size_t index) const {
            return OneDArrayProxy(&buf[index * n_cols], n_cols);
        }
    
        std::size_t rows() const { return n_rows; }
        std::size_t columns() const { return n_cols; }
    };
    
    模板
    二类达雷{
    私人:
    std::大小n行;
    标准:大小不一致;
    std::载体buf;
    公众:
    类代理{
    私人:
    T*rowptr;
    标准:尺寸与冷尺寸;
    公众:
    OneDArrayProxy(const T*rp,std::size_T cs):rowptr(const_cast(rp)),colsize(cs){
    常量和运算符[](标准::大小索引)常量{
    返回rowptr[index];
    }
    运算符[](标准::大小索引){
    返回rowptr[index];
    }
    std::size\u t size()常量{return colsize;}
    };
    TwoDArray(std::size_t rows,std::size_t cols):n_rows(rows),n_cols(cols),buf(rows*cols){}
    TwoDArray():TwoDArray(0,0){}
    OneDArrayProxy运算符[](标准::大小索引)常量{
    返回一个DarrayProxy(&buf[index*n_cols],n_cols);
    }
    std::size_t rows()常量{返回n_rows;}
    std::size\u t columns()常量{return n\u cols;}
    };
    
    用法示例:

    int main()
    {
        TwoDArray<int> arr(9, 5);
        for (std::size_t i = 0; i < arr.rows(); i++) {
            for (std::size_t j = 0; j < arr.columns(); j++) {
                arr[i][j] = i * 10 + j;
            }
        }
    
        for (std::size_t i = 0; i < arr.rows(); i++) {
            // you can use the array element's 'size()' function instead of 'columns()'
            for (std::size_t j = 0; j < arr[i].size(); j++) {
                std::cout << arr[i][j] << " ";
            }
            std::cout << std::endl;
        }
    }
    
    intmain()
    {
    两个darray-arr(9,5);
    对于(std::size_t i=0;iSTD:在C++中,不要使用<代码> Malc C <代码>,甚至不要>代码>新< /Cord> 2D数组,使用<代码>向量<代码>“我只需要调用FP(p)来释放内存吗?没有循环(?),因为有一个分配。但是,请不要返回<代码> MalCube()/<代码>的返回值。真的。那么,不要使用<代码>新< /代码>。(numRows*numCols)
    ,将其封装在一个类中,重载
    操作符[]
    返回一个代理对象,该代理对象的指针(或任何东西)指向向量中的适当行,重载其
    操作符[]
    等。在C语言中,您不能使用
    new
    。您希望讨论哪种语言?此外,错误是因为您分配了错误的类型。您可以使用
    new(int[4])[2]
    然后返回对象的类型将是
    int(*)[4]
    ,因为
    new T
    会产生一个类型为
    T*
    的对象。所以,如果你分配一个指向数组的指针,你会得到一个指向数组的指针。当你说“不能在c++中实现”时,你的意思是“不能使用new实现”吗我粘贴的代码是用C++编译的,而不是MaloC是C++的一部分。问题是类型,而不是<代码> MARROCKE()/Calue>。
        p = new (int[2][4]);
    
    template<typename T>
    class TwoDArray {
    private:
        std::size_t n_rows;
        std::size_t n_cols;
        std::vector<T> buf;
    
    public:
        class OneDArrayProxy {
        private:
            T *rowptr;
            std::size_t colsize;
    
        public:
            OneDArrayProxy(const T *rp, std::size_t cs) : rowptr(const_cast<T *>(rp)), colsize(cs) {}
            T const &operator[](std::size_t index) const {
                return rowptr[index];
            }
    
            T &operator[](std::size_t index) {
                return rowptr[index];
            }
    
            std::size_t size() const { return colsize; }
        };
    
        TwoDArray(std::size_t rows, std::size_t cols) : n_rows(rows), n_cols(cols), buf(rows * cols) {}
        TwoDArray() : TwoDArray(0, 0) {}
    
        OneDArrayProxy operator[](std::size_t index) const {
            return OneDArrayProxy(&buf[index * n_cols], n_cols);
        }
    
        std::size_t rows() const { return n_rows; }
        std::size_t columns() const { return n_cols; }
    };
    
    int main()
    {
        TwoDArray<int> arr(9, 5);
        for (std::size_t i = 0; i < arr.rows(); i++) {
            for (std::size_t j = 0; j < arr.columns(); j++) {
                arr[i][j] = i * 10 + j;
            }
        }
    
        for (std::size_t i = 0; i < arr.rows(); i++) {
            // you can use the array element's 'size()' function instead of 'columns()'
            for (std::size_t j = 0; j < arr[i].size(); j++) {
                std::cout << arr[i][j] << " ";
            }
            std::cout << std::endl;
        }
    }