使用 new for 2D 数组重写此 malloc
Rewrite This Malloc Using New For 2D Array
经过一些反复试验,我找到了一种方法来对 2D 数组进行 malloc 处理,使其在内存中是连续的,相当于非动态情况。
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) 来释放内存吗?没有循环?
- 我如何将其转换为使用新的,而不是 malloc?
我试过了
p = new (int (*)[4])[2];
但这给出了错误:
error: cannot convert int (**)[4] to int (*)[4] in assignment
下面是
一个类模板,它使用一个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; }
};
使用示例:
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;
}
}
你不能
在C++这样做。您的malloc()
代码是完全有效的 C,但不是有效的C++。它不适用于new
.
C++要求数组类型具有恒定大小,但 C 允许动态大小的数组类型。一维数组只有一个例外,可以在C++中以动态大小分配,但仅此而已。在 2D 数组中,第二个大小必须在编译时知道。
这是C比C++强大得多的一点。
说服g++
在这方面遵循标准需要一点时间,但是编译这个小程序
#include <stdlib.h>
int main(int argc, char** args) {
int (*foo)[argc];
}
与g++ -pedantic -std=c++11 foo.cpp
尽职尽责地生成错误消息:
foo.cpp: In function ‘int main(int, char**)’:
foo.cpp:4:17: warning: ISO C++ forbids variable length array ‘foo’ [-Wvla]
1)是的,你可以打电话给free()
但请注意,您正在执行指针别名(指向不同类型的 2 个指针,int 和 int[] 具有相同的地址),这可能会导致细微的优化错误。 在C++使用malloc()
是一种非常糟糕的做法,应该const
numcols 。
2)在C++中执行此操作的方法是使用[<array>][2]
如果在编译时知道大小:
array<array<int, 4>,2> a;
更灵活的替代方法是使用允许动态大小和调整大小的向量:
vector <vector <int>> b(2, vector<int>(4));
3)使用新的你也可以做:
p = new (int[2][4]);
第一个维度也可以是可变的,但第二个维度必须是常量。 但我鼓励您使用标准的遏制器替代方案之一。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 如果没有malloc,链表实现将失败
- 将OpenCV C++重写为EmguCV C#-如何使用指针
- malloc() 可能出现内存泄漏
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 在 C++ 中用派生类型重写成员函数
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 方法重写线程C++中的概念
- 为重写std::exception的库生成swig接口时出错
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 在C++中创建队列 - 什么是 malloc 错误?
- 如何在 malloc 内存中初始化非 POD 数据
- 如何强制从重写方法调用重写的方法基方法?
- 用于C++的静态二进制检测或二进制重写工具和框架
- 如何将 if else 语句重写为 switch 语句
- 如何重写全局方法名称以在调用原始方法之前将我的代码推到前面
- 使用 malloc() 时出现意外大小
- C++:在被本地字符串捕获后释放或销毁 malloc'd char *?
- 使用 new for 2D 数组重写此 malloc
- mmap被破坏,是malloc重写内存中的元素