C++ 使用新的For 2D数组重写此Malloc
经过一些尝试和错误,我找到了一种方法来malloc一个2D数组,这样它在内存中是连续的,相当于非动态情况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
int numRows =2;
int numCols = 4;
int (*p)[numCols];
p = (int (*)[numCols]) malloc(sizeof(int)*numRows*numCols);
所以p现在基本上和我做int p[2][4]时一样,只是它在堆上而不是堆栈上
2个问题:
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;i STD:在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;
}
}