views:

1306

answers:

2

How do I concatenate two arrays to get a single array containing the elements of both original arrays?

+1  A: 

Generally speaking, in plain C, you can't merge two arrays.

The issue is that C does not really have arrays at all. The a[b] notation is only syntactic sugar for point addition and dereference: *(a + b). The variable a is only a pointer, so it does not record the array length, so concatenation is not possible.

So, how do we get the array length? Another question that needs answer is how should the new array be allocated?

ddaa
Incorrect. C *does* have array objects. When array obejects are used in expressions, the array type "decays" to pointer type most (but not all) of the time. This, however, does not mean in any way that C really has no arrays at all.
AndreyT
... and if object `a` is declared as an *array*, object `a` (more precisely - its type) *does* "record" the array length, of course.
AndreyT
AndreyT: Can you provide a reference to back this claim? In C++ STL, sure there is an array<> class template. But not in plain C to the best of my knowledge, and according to _The C Programming Language_ 2nd Edition.
ddaa
AndreyT is right about this. In most a[b] expressions you can consider it to be syntactic sugar, but what about declarations? When I declare int a[10]; then C is creating an array object, of size 10 * sizeof(int), as a first class citizen. The compiler knows how big the array is, and generates code that allocates that much space.
Bill Forster
That's a very weak definition of "array type". The only way to get the array size is using sizeof.
ddaa
What is your point ? The only way to get the size of an integer is using sizeof too. C supports array objects/types as a native part of the language. Sure the support is not as rich and comprehensive as a more modern language, but it suits C as a lightweight language. What do you think int a[10]; means in C if not the instantiation of an array of 10 ints?
Bill Forster
When I read "array type" I assume a data structure that records its length. In C, the size of an array is part of the declaration. When you pass an array pointer to a subroutine, the size needs to be provided as an additional parameter.In my mind, "int a[10];" always meant "allocate 10 ints of automatic/static/struct memory and define a as the pointer to the first element". That's a pointer and some memory. Not an array object.
ddaa
Okay I see your point now. I see this as C having very lightweight support for arrays. You see this as C not having real support for arrays at all. I suspect we are actually arguing about semantics more than anything else.
Bill Forster
I've been pretty sure we were arguing semantics for a couple of comments. But somehow, I preferred looking silly for arguing semantics, rather than silly for potentially misunderstanding a lesser known point of the C language :-)
ddaa
+12  A: 

Arrays in C simply are a contiguous area of memory, with a pointer to their start*. So merging them involves:

  1. Find the length of the arrays A and B, (you will probably need to know the number of elements and the sizeof each element)
  2. Allocating (malloc) a new array C that is the size of A + B.
  3. Copy (memcpy) the memory from A to C,
  4. Copy the memory from B to C + the length of A (see 1).
  5. You might want also to de-allocate (free) the memory of A and B.

Note that this is an expensive operation, but this is the basic theory. If you are using a library that provides some abstraction, you might be better off. If A and B are more complicated then a simple array (e.g. sorted arrays), you will need to do smarter copying then steps 3 and 4 (see: how do i merge two arrays having different values into one array).


  • Although for the purpose of this question, the pointer explanation will suffice, strictly speaking (and for pacifying the commenter below): C has the concept of an array, that can be used without the syntax of pointers. Implementation wise, however, a C array and a contiguous area of memory, with a pointer are close enough they can be, and often are, used interchangeably.
Chen Levy
Where did "...with a pointer to their start..." come from? When I declare `int a[10]` I get a contiguous area of memory with 10 `int` in it and no pointers whatsoever.
AndreyT
@AndreyT: `a` is your pointer. You appear to be aware of this in your comment on the other answer...
Shog9
@Shog9: `a` is not a pointer. `a` is an array. When the array type decays to pointer type, the resultant pointer is just an intermediate temporary value, which has nothing to do with `a`. Wnat the post above states is incorrect, unless it talks specifically about `malloc`ed arrays.
AndreyT
A bit pedantic, eh? For the purpose of the algorithm described, it makes no difference (apart from the necessity of skipping step #5 in the case of stack-based arrays).
Shog9
Stating that array is not a pointer is *not even remotely* pedantic. This is a rather popular and annoying misconception, so having it promoted here is definitely not a good idea.
AndreyT
@Shog9: int a[10] a in the symbol table has the memory address of the first element of a. this memory address call it whatever you want, is a memory address and not a C pointer. char *p, p in a symbol table has the address of a location to store p's value, and that value in a pointer to another value of type char. There is an extra dereference when using pointers and accessing them compared to arrays.
prime_number