2010-02-07 68 views
1

我被我的教授给了一个问题。由于数据类型的原因,使用void指针创建动态2D数组而非int指针更为一般。如何使用void指针在C++中创建二维数组?

但我不知道如何使用创建 - >void***m // data type is void* pointer

任何人都可以给出这样的例子?感谢您的回答,非常感谢!

+0

告诉你的教授,直接使用内联asm和访问索引寄存器比使用void指针访问数组要普遍得多。 –

+0

你能举个例子吗?一段我可以编译的代码。谢谢! – zhen

+0

这和你以前的问题有什么不同? http://stackoverflow.com/questions/2212506/how-do-you-use-a-void-pointer-to-generate-2d-dynamic-array – interjay

回答

0

如果我不得不这样做的,我会采取的方法是使用分配

new unsigned char[<max size in bytes>] 

然后我会创建一个模板类访问数组的内存。例如:

template<class ElementType, int numBytes> 
class DynamicArray 
{ 
public: 
    DynamicArray(unsigned char* buffer); 
    ElementType& Get(long index); 
    void Set(long index, const ElementType &element); 
private: 
    ElementType* m_array; 
}; 

在您的getter/setter方法的模板化实现中,您只需访问m_array。你可以通过乘以sizeof(ElementType)来检查索引是否有效,然后验证它是否小于numBytes。

构造函数将简单地将缓冲区转换为ElementType *并将其分配给m_array;

然后,您可以使用字节分配数组,然后以不同的格式正是如此访问:

unsigned char* buffer = new unsigned char(1000); 
DynamicArray<long, 1000> longArray(buffer); 
long val = 10; 
longArray.Set(0, val); 
longArray.Get(0); 

DynamicArray<short, 1000> shortArray(buffer); 
short firstTwoBytes = shortArray.Get(0); 
etc. 

我会做这种方式的原因是,它给你最大的编译时类型安全。这是C++模板非常擅长的一件事。您可以使用与上述代码演示的模板类的多个实例相同的缓冲区。我没有尝试编译这个,所以我很抱歉,如果有任何语法错误。

顺便说一句,你可以使用操作符重载使数组访问器看起来像是一个'C'数组。以STL的“矢量”类为例。

+0

太棒了!谢谢你的解释! – zhen

2

数组引用非常简单。可以说B是数组的基地址(起始地址),S是一个元素的大小,I0是一个数组的索引。

在一个维数组的情况下,元素的地址是:

B + (S * I0) 

可以将此扩展到多个维度,但是现在你需要知道数组的其他方面。比方说你有一个尺寸D1,D0二维数组和索引I0,I1元素的地址是:

B + (D1 * I1 * S) + (S * I0) 

三维阵列将

B + (D2 * I2) * (D1 * I1 * S) + (S * I0) 

等。

在你的空指针的情况下,为int的二维数组:

int D1 = 10, D0 = 20, I1 = 5, I0 = 5; 
void * base; 

base = malloc((D1 * D0) * sizeof(int)); 
int value = *((char*)base + (D1 * I1 * sizeof(int)) + (sizeof(int) * I0)); 

注意,我不得不投的空指针为char *,使指针运算将在的sizeof()来完成单位。尽管这可能是一般性的,但我不认为我会多用它;-)但它确实有助于理解数组索引是如何工作的。