如何使用 void 指针生成 2D 动态数组?
Posted
技术标签:
【中文标题】如何使用 void 指针生成 2D 动态数组?【英文标题】:How do you use a void pointer to generate 2D dynamic Array? 【发布时间】:2010-02-06 08:20:36 【问题描述】:有谁知道如何使用 void 指针而不是 int 指针来生成二维数组?
对于整数指针,我这样做:
int **m;
m = new int* [row];
for(int i=0; i< row; i++)
m[i] = new int[col];
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
m[i][j] = rand () % 10;
如果指针类型是void***m怎么办?
如何定义像 int 这样的存储? eg.(m = new int* [row];)
感谢您的帮助。
请允许我更清楚地说明我的问题,我得到了这些:
class Matrix
public:
Matrix();
Matrix(int,int);
void printMatrix();
private:
int row;
int col;
void***m;
void initMatrix(); // Initialize the storage for row and column
void generateMatrix (); // construct a 2D array
【问题讨论】:
为什么要这样做?你想达到什么目的?此外,这对您来说可能很紧急,但对我们来说不是,所以请冷静下来,更清楚地说明您的问题,以便我们更好地为您提供帮助。 我删除了“紧急!请!”从你的标题开始。在 SO 上这里不合适。 我认为你在“如果指针类型是......”中有一个额外的“*” 致 Chris Lutz:感谢您的提醒。但我不认为你知道答案。致 T.J.Crowder:感谢编辑我的帖子。对 Manuel:不,它是一个 void* 类型的指针,用于创建二维数组。这个问题是我教授给的,好像没人能解决。 @zhen:我知道英语可能不是你的主要语言,但这对克里斯来说很粗鲁;没必要这样做。 【参考方案1】:您的问题可能最好通过解释void
的含义来回答。
void
基本上表示没有类型。因此,您不能告诉编译器创建void
类型的对象,例如带有以下语句:
new void
new void[...]
这些表达式的含义大致如下:分别是“创建某物”或“创建某物的数组”。对于编译器来说,这显然不够精确。
void*
(指向void
的指针)是允许的,因为指针对编译器来说基本上总是相同的东西:另一个对象的内存地址。您可以将指针视为某种指向某物的箭头。如果您正在使用指针,编译器会看到该箭头,而不是它指向的实际内容。因此编译器并不关心“目标类型”是void
。
然而,这样做的结果是您不能取消引用 void*
(指向 void
的指针),因为这样会使编译器有效地查看指向的事物,这将是 void
值,这对编译器没有任何意义。
总结:
1)您不能创建void
类型的数组,如new void[...]
。
2)您可以创建一个指向void
(void*
) 的指针,甚至是一个指向void*
(void**
) 的指针.
3)你不能取消引用void*
指针(但你可以取消引用void**
指针)。
结论:
4)您可以创建一个int*
数组并让void*
引用它:
int** m;
// ... (create the dangling array as in the OP's code and let m point to it)
void* v = (void*)m;
(请参阅下面的 cmets,了解为什么这里使用 void*
而不是 void**
!)
5) 因为语句#3,你可以合理地使用这样一个指针做的就是传递它,但是你不能处理数组的实际内容。为此,您需要将其类型转换回正确的数据类型:
int **m2 = (int**)v;
【讨论】:
在void **v = (void **)m;
中,v
不是void
指针。你的意思是void *v = (void *)m;
?
还是很奇怪。你为什么写void** v = (void**)m;
而不是void* v = m;
? (通知***.com/questions/560845/…)【参考方案2】:
使用您在对另一个答案的评论中发布的 sn-p,可以更轻松地为您提供帮助。
class Matrix
private:
int row;
int col;
void** m;
初始化表格行的代码可能是这样的:
m = malloc(sizeof(int*) * row);
希望你自己可以用它来解决剩下的作业。
【讨论】:
【参考方案3】:a void* 是指向某些未指定类型的指针。当然,在通常情况下,指针与 int 大小完全相同,这是一个令人高兴的意外,因此实际上没有任何东西阻止您编写:
int **m;
m = new int* [row];
for(int i=0; i< row; i++)
m[i] = new int[col];
for (int i = 0; i < row; i++)
for (int j = 0; j < col; j++)
m[i][j] = rand () % 10;
void ***v = (void ***)m; // v is a 2-d array of void* pointers now!
当然,我不确定您为什么要为 Matrix 类创建一个 void*** 数组。也许是自定义数字数据类型?
【讨论】:
哇 会破坏某些架构。我永远不会建议假设void*
与 int
大小相同。
投票赞成使用问题内容并在末尾添加简单的类型转换。
@T.J Crowder,是的,这并不是我提倡的任何东西,但考虑到问题的限制,我无法想象教授想要什么。
将int**
转换为void***
看起来很危险。
取决于编译器设置。在 Visual Studio 中,如果希望指针大小为 8 字节或保持在 4 字节,则可以在 64 位模式下指定。尽管假设 void* 与 int* 大小相同,但我认为这个答案没有任何问题。尽管它仅取决于编译器设置,但在这里我断言您假设 int void* 与 int 大小相同。【参考方案4】:
你不能。如果您负责创建数组,则需要知道元素的大小。使用void *
,您对它所指向的内容一无所知。您必须让调用者为您提供大小参数或其他东西。
编辑:也许第三个*
是关键:他是在要求你创建一个void *
的二维数组吗?毕竟,void *
和int
一样多是一种类型。在你说new int[col]
的地方你应该可以说new void * [col]
。您没有显示足够的代码让我真正了解您的操作方式,但如果它与int**
一起使用,那么它应该与void***
一起使用,只需执行搜索和替换即可int
=> void *
.
【讨论】:
我得到了一个如下的类:class Matrix private: int row;国际单位;无效***米;如果我需要生成一个 2x2 数组怎么办? 您能否举例说明如何使用 void* 指针创建二维动态数组?谢谢! 也许您需要弄清楚课堂上给您的问题的答案,而不是要求其他人为您解决?无论如何,你不能分配一个“动态”数组 - 没有这样的东西(除非你分配像 std::vector 这样的东西)。【参考方案5】:由于每个指针类型都可以隐式转换为void*
,因此您可以像处理int*
一样将其分配给void*
。
问题出在哪里?我错过了什么吗?
【讨论】:
【参考方案6】:我能想到的最接近的答案是以下一个。您可以将二维数组创建为整数向量,然后将其传输为 void *。这与它在内存中的存储方式非常相似。
const unsigned int MaxRow = 10;
const unsigned int MaxColumn = 10;
void print(void * m)
int * matrix = (int *) m;
for(unsigned int i = 0; i < MaxRow; ++i)
for(unsigned int j = 0; j < MaxColumn; ++j)
std::printf( "%03d ", matrix[ ( i * MaxColumn ) + j ] );
std::printf( "\n" );
int main()
// Create
int * matrix = new int[ MaxRow * MaxColumn ];
for(unsigned int i = 0; i < MaxRow; ++i)
for(unsigned int j = 0; j < MaxColumn; ++j)
matrix[ ( i * MaxColumn ) + j ] = ( i * MaxColumn ) + j;
// Show
print( matrix );
delete[] matrix;
return 0;
【讨论】:
以上是关于如何使用 void 指针生成 2D 动态数组?的主要内容,如果未能解决你的问题,请参考以下文章
Qt中的2D游戏:初始化怪物并将动态分配的数组作为指针参数传递[关闭]