0

Let's say I've got a unsigned char pointer (uchar* from now on) to the beginning of an array of type T different from uchar. Knowing the size of this array and that it is continuous (created using malloc), is it possible to copy it to another array without knowing the type T? How can I access it byte per byte?

Thanks

Renan
  • 1,910
  • 4
  • 22
  • 36
  • 2
    Do you know the size of the array in bytes or in number of elements? – TheJuice Jun 15 '11 at 08:37
  • How come you don't know the type `T`? Sounds to me like you're mixing C and C++, which is rarely a good idea. – fredoverflow Jun 15 '11 at 08:42
  • For reasons way too long to explain, I can't use a template class. My solution then was to store the data I need in this 'generic' pointer. But because of that I can't know the real type. – Renan Jun 15 '11 at 08:46
  • why just casting your `uchar*` to `T*` isn't enough? If you know the size of the array and the size of `T` (as you say) than you know the number of elements in the array, so you are on the safe side – davka Jun 15 '11 at 08:50
  • @dav: How can you cast to `T*` without knowing `T`? – fredoverflow Jun 15 '11 at 08:51
  • @Davka: how would I access the element? Would it be `*((T*)(data + 5))` [for instance to access the element of index 5]? – Renan Jun 15 '11 at 08:55
  • @Renan: No, it would be `((T*)data)[5]`. But of course that only works if you know the type `T`. Do you? – fredoverflow Jun 15 '11 at 08:58
  • @Fred: correct, it's knowing the size of T vs. knowing T confused me – davka Jun 15 '11 at 09:00
  • @Renan: I'd `T* t = reinterpret_cast(data); t[5];`, but as @Fred remarked, you must know the `T` – davka Jun 15 '11 at 09:02
  • 1
    How come the question has "C" in the title but is tagged "C++"? – fredoverflow Jun 15 '11 at 09:51

2 Answers2

6

You can make a shallow copy of everything with a simple memcpy or memmove, but you better be sure that the array elements are no class objects that contain any pointers. Or more precisely, make sure they are PODs.

Community
  • 1
  • 1
Xeo
  • 129,499
  • 52
  • 291
  • 397
  • 1
    Totally wrong if you do not know the array size you cannot use memcpy or memmove. – VGE Jun 15 '11 at 08:36
  • @VGE: the OP says the array size is known. – Tom Jun 15 '11 at 08:39
  • @VGE: "Knowing the size of this array and that it is continuous" -- taken verbatim from the OP. – Xeo Jun 15 '11 at 08:40
  • @VGE But hasn't Renan mentioned that array size is known? – Bojan Komazec Jun 15 '11 at 08:41
  • @VGE: But I do know the array size @Xeo: If I know the size of each element, is it possible to access them individually? – Renan Jun 15 '11 at 08:42
  • It is not enough you have to know the size of T. and you cannot know size of T without knowing T. memory size = sizeof(T) * #items. – VGE Jun 15 '11 at 08:42
  • @Renan: What exactly do you mean by "access" the element? If you don't even know the type `T`, what do you want to do with the element? – fredoverflow Jun 15 '11 at 08:48
  • @VGE: If you know the size of the array, simply `memcpy`ing each byte will achieve what the OP is asking for. `memcpy` doesn't need to know the correct amount of elements since we're talking about bytes anyways. – Xeo Jun 15 '11 at 08:49
  • @Renan, unless your are just copying bytes around, you'd need to know the type `T` to do anything useful with it. – Node Jun 15 '11 at 08:50
  • 1
    They can be PODs and still contain pointers to itself or to other objects in the array. Using memcpy will break in that case. – Bo Persson Jun 15 '11 at 09:58
0

You could do something like this:

T foo; // your given arbitrary object
T bar; // target

unsigned char * p = reinterpret_cast<unsigned char *>(&foo);  // type-punned
unsigned char * q = reinterpret_cast<unsigned char *>(&bar);  // ditto

memcpy(q, p, sizeof(T)); // copy byte-wise

If T has non-trivial properties (custom constructors, pointers to heap variables, etc.), this has lots of potential to cause trouble, but you can certainly access the raw data via those pointers. (Doing this in general may be fun for instance if you want to look at the binary representation of a double or something like that, but in production code this should rarely come up.)

If your original object is T foo[N], use the size sizeof(T) * N.

Edit: Do you mean that you want this to work for an arbitrary type or for an unknown type? If you don't know the size of T (e.g. if you are only handed the pointer), then of course you cannot do it because you don't know how much memory is occupied. There are no "field delimiters" or anything like that stored in memory that you could inspect at runtime.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084