1

I was given a question from my prof. that to use a void pointer to create a dynamic 2D array rather than int pointer due to the data type is more general.

But I've no idea how to create by using -> void***m // data type is void* pointer

Anyone can give an example on this? Appreciate your answer, many thanks!

3
  • Tell your prof that using inline asm and accessing index registers directly is much more general than using void pointers for array accessing. Commented Feb 7, 2010 at 13:41
  • Can you please give an example please? a piece of code that I can compile. Thanks! Commented Feb 7, 2010 at 13:50
  • How is this different from your previous question? stackoverflow.com/questions/2212506/… Commented Feb 7, 2010 at 14:26

2 Answers 2

2

An array reference is pretty simple.

Lets say that B is the base address of the array (the starting address), S is the size of an element and I0 is an index into an array.

In the case of a one dimensional array, the address of an element is:

B + (S * I0)

You can extend this to multiple dimensions, but now you need to know the other dimensions of the array. Lets say you have a two dimensional array with dimensions D1, D0, and indices I0, I1 the address of an element is:

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

A three dimensional array would be

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

and so on.

In the case of your void pointer, for a two dimensional array of 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));

Note that I had to cast the void pointer to char* so that pointer arithmetic would be done in sizeof() units.

Even though this might be general, I don't think I'd use it much ;-) It does help to understand how array indexing works, though.

Sign up to request clarification or add additional context in comments.

Comments

0

If I had to do it that way, the approach I'd take would be to allocate the memory using

new unsigned char[<max size in bytes>]

Then I'd create a templated class to access the array. Something like:

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;
};

In your templated implementations of the getter/setter methods you'd simply access m_array. You'd check that index was valid by multiplying it by sizeof(ElementType) and then verifying that it was less than numBytes.

The constructor would simply cast buffer to ElementType* and assign that to m_array;

You could then allocate the array using bytes and then access it in different formats thusly:

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.

The reason I would do it this way is that it gives you maximum compile-time type safety. That's one thing that C++ templates are really good at. You can use the same buffer with multiple instances of this templated class as demonstrated by the code above. I didn't try to compile this, so I apologize if there are any syntax errors.

BTW, you could use operator overloads to make the array accessors look like they were a 'C' array. See the STL's "vector" class for an example.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.