如何使用 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 动态数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用指针从2D char数组中生成一个句子

Qt中的2D游戏:初始化怪物并将动态分配的数组作为指针参数传递[关闭]

将数组作为 void 指针发送时,在 c 中使用 puts 输出 2d char 数组时出错

如何在 C++ 中初始化指向动态二维数组的指针 [关闭]

如何使用嵌套的 for 循环将两个 2d(倾斜)数组相加?

使用 2D 字符数组时将数组作为指针