#include <iostream>
char** make2D(const int dim1, const int dim2)
{
char* toAlloc;
const int size = (dim1 * dim2) + dim2;
toAlloc = new char[size];
for(int i = 0; i < dim2; i++)
{
toAlloc[i] = reinterpret_cast<char>(&toAlloc[(dim2 + (dim1 * i))]);
}
return reinterpret_cast<char**>(toAlloc);
}
int main(void)
{
int dim1 = 8;
int dim2 = 10;
char** array2D = make2D(dim1, dim2);
for (int i = 0; i < dim2; ++i)
{
array2D[i][i % dim1] = i + 100; // << Crash
}
return 0;
}
我试图通过单个分配来分配二维数组。所以,我的算法是,前10个(这个代码中的dim2
)项目具有指向每行的第一项的指针。
当我通过指向'int'的方式尝试这个时,
int** make2D(const int dim1, const int dim2)
{
int* toAlloc;
const int size = (dim1 * dim2) + dim2;
toAlloc = new int[size];
for(int i = 0; i < dim2; i++)
{
toAlloc[i] = reinterpret_cast<int>(&toAlloc[(dim2 + (dim1 * i))]);
}
return reinterpret_cast<int**>(toAlloc);
}
int main(void)
{
int dim1 = 8;
int dim2 = 10;
int** array2D = make2D(dim1, dim2);
for (int i = 0; i < dim2; ++i)
{
array2D[i][i % dim1] = i + 100;
}
return 0;
}
它工作正常,但当我在char中执行此操作时,它在上面的代码中的注释行崩溃。
我对崩溃的想法是当我做reinterpret_cast
时,由于指针(8byte)和char(1byte)之间的内存大小差异而发生了一些事情。所以,听起来很荒谬......将指针(8byte)更改为int(4byte)很好,但是当我进行更大幅度的渲染(8byte到1byte)时,会导致一些问题......
我不知道为什么char不起作用但int工作。你能提出一些建议来使char案件有效吗?
回答这个问题是有一个区别,一个巨大的,在很多平台上,一个指针可能适合一个int,在很少的平台上它将适合一个char。在64位的现代PC上,没有一种是存储指针的安全方法。
如果尺寸是静态的,请使用vector或array等容器。尝试类似的东西:
array<array<T, dim2>, dim1> variable{};
如果你真的想要一个T型的二维数组;因为你似乎需要一个指针数组尝试类似的东西:
array<array<T *, dim2>, dim1> variable{};
这将为你的平台制作一个适当类型的数组存储指针,无论实际指针有多大,显然你应该用你要指向的数据的正确类型替换T,这将确保指针数学是适合你的。数组类型的大小将在编译时计算,如果你需要动态大小,你应该使用向量,在向量上调用resize和所有子向量之后,确保尽可能少地分配所有内存。
也请不要使用reinterpret_cast或c-style演员,除非你非常清楚自己在做什么,否则它会成为灾难的秘诀。
不知道你正在读什么书或谁教你C ++,但请改变你的知识来源。
不鼓励使用原始拥有指针,并且在很多方面使用它们的方式都是错误的。切勿将指针存储在除指针类型之外的任何内容中。即使在平原C中,如果你需要施放,你至少应该施展至无效*。
如果你真的想直接存储/传递指针,请阅读unique_ptr或shared_ptr。
如果您坚持使用容器的原始指针,请尝试使用清理程序(如地址清理程序,内存清理程序)来构建代码(这些至少由clang和gcc支持,现在可能更多的编译器)
问题是对象大小的“不兼容性”:
sizeof(char)
是1
sizeof(int)
通常是4
或8
(但至少2
)。sizeof(T*)
,一般是4
或8
,std::uintp_t
可以保持void*
值,这对于int
不太必要(甚至更少与char
)。你不能安全地将void*
存放到char
或int
。它发生在为int
工作,但它不便携。
reinterpret_cast
通常是错误的工具。
更简单的是创建一个class Matrix
,使用std::vector<T>
和accessor来修复索引。 (你甚至可能有代理允许m[2][3]
语法)。
拥有原始指针,您需要新的展示位置,并提供正确的删除...