Click here to Skip to main content
15,878,852 members
Please Sign up or sign in to vote.
2.33/5 (3 votes)
See more:
Hi!
I want to concatenate 2 array as follows:
C++
double little_arrayA[] = {1, 2, 3, 4, 5};
double little_arrayB[] = {6, 7, 8, 9, 10};

double *BIG_array = new double [2*5];

//START "BLOCK 1" (concatenate by using reference operator '&')
&BIG_array[0] = little_arrayA;
&BIG_array[5] = little_arrayB;
//END "BLOCK 1"


Obviously I can not compile this code but I would like to understand how to implement the function in "BLOCK 1" in the most efficient way. For efficiency, using cycle seems unsuitable, but rather I wanted to use not working reference operator '&'.
Do you have any idea?

Thank you!

Sergio

EDIT:
I thank you for all the information received! Hoping to do a bit of clarity, I present below some constraints to be considered:
1) I have to concatenate 2 array of double in a single array of double.
2) By the word "efficiency" I mean perform the function in the shortest possible time.
3) Each array is large/very large.
4) I don't know array size in compile time.
Posted
Updated 19-Apr-12 2:42am
v2
Comments
Philippe Mori 18-Apr-12 22:54pm    
That question does not make much sense... & is the address-of operator when used that way. Thus, on the left-hand side, you have a pointer... but it cannot be modified (think of it as a constant pointer). And operator= is a member function when overloaded so it not possible to overload it as the left-hand side is a pointer.

You should learn to use STL and avoid low-level stuff like that. Uses classes like std::vector<double> instead.
[no name] 18-Apr-12 23:24pm    
If you had offered this as a solution I would have voted for it.
cammaratasergio 19-Apr-12 6:39am    
I agree with you:). In fact, I wrote that "OBVIOUSLY I can not compile this code but I would like to understand how to implement the function in the most efficient way."
Philippe Mori 19-Apr-12 8:08am    
Well efficiency in that academic context is not that much useful. In a real application, the most efficient way would depend a lot on what you are doing.

For small arrays like that it won't matter much and for larger arrays or operation done in large loops, the performance will generally depends much more on what is around that code than the code itself.
cammaratasergio 19-Apr-12 10:51am    
Thanks to all!
At the end, given that I use not overlapping memory blocks, I prefer memcpy.
Moreover, it would seem that memcpy is more efficient than std::copy(). (http://stackoverflow.com/questions/4707012/c-memcpy-vs-stdcopy)

// EDIT
How about it ? :) :
C++
template <typename T>
class Concatenation {
  T* m_pDataA;
  int m_iCountA;
  
  T* m_pDataB;
  int m_iCountB;

public:
  Concatenation(T* pDataA, int iCountA, T* pDataB, int iCountB)
  : m_pDataA(pDataA), m_iCountA(iCountA)
  , m_pDataB(pDataB), m_iCountB(iCountB)
  {
    // some assertions... :)
  }

  T* GetAt(int iIdx)
  {
    // some assertions... :)

    T* pResult(NULL);

    if (0 <= iIdx && iIdx < (m_iCountA + m_iCountB)) {
      if (iIdx < m_iCountA) {
        pResult = &m_pDataA[iIdx];
      } else {
        pResult = &m_pDataB[iIdx - m_iCountA];
      }
    }

    return pResult;
  }
};

void Test(int iCountA, int iCountB)
{
  // some assertions... :)

  int* pIntA(new int[iCountA]);
  int* pIntB(new int[iCountB]);

  Concatenation<int> cCat(pIntA, iCountA, pIntB, iCountB);
  *cCat.GetAt((iCountA + iCountB) /2) = 123;
  ASSERT(123 == *cCat.GetAt((iCountA + iCountB) /2));

  delete[] pIntA;
  delete[] pIntB; 
}
 
Share this answer
 
v6
Comments
enhzflep 19-Apr-12 9:58am    
Good generalized answer.
Poor solution where speed is paramount.

If type was char, there would be a copy operation for each element in each array. Using memcpy, copying may be optimized(by the memcpy function) such 8 or more bytes are copied per cpu instruction - an 8 times improvement in speed of the basic copying, and without the overhead of the class.
Eugen Podsypalnikov 19-Apr-12 10:05am    
Thank you,
but I can not see any copy operation here, for <char> as well... :)
enhzflep 19-Apr-12 10:10am    
Oh my goodness. I'm more tired than I had realized. I'd misread the first if statement as a for-loop.

Despite my overwhelming urge to delete my initial comment and hide my embarrassment, I will leave it in place as a testament to my stupidity.

You sir, clearly have the fastest method - also the one that satisfies the question as posed. Would you accept a 5 from a fool? :slinks-away:
Eugen Podsypalnikov 19-Apr-12 10:25am    
Thank you ! :)
[no name] 19-Apr-12 10:26am    
Very neat a 5 for that anyway.
I think this test is wrong - just a typo:
if (0 <= iIdx && iIdx < (m_iCountA + m_iCountA)) {
This does not however create a new array and that may be a requirement.
If you're interested in a C++ solution, have a look at std::copy()[^]. It will get you away from all the looping misery.

If you want a C version, take a look at pwassers solution.
 
Share this answer
 
All these arrays are in different and not contiguous locations in memory. To get the contents all in one place efficiently this is one option.

C#
double little_arrayA[] = {1, 2, 3, 4, 5};
double little_arrayB[] = {6, 7, 8, 9, 10};


double *BIG_array = (double *) new char [sizeof(little_arrayA) + sizeof(little_arrayB)];


memcpy(BIG_array, little_arrayA, sizeof(little_arrayA));
memcpy(BIG_array + sizeof(little_arrayA), little_arrayB, sizeof(little_arrayB));
 
Share this answer
 
Comments
Philippe Mori 19-Apr-12 8:03am    
If the size is known at compile time, it can even be more efficient by declaring the resulting array on the stack.
enhzflep 19-Apr-12 9:54am    
Can't possibly get any quicker than this approach using memcpy.
Given that the array sizes aren't known at compile time, the sizeof operator won't work correctly, but it doesn't matter, since you already know sizeof(double) and number of elements in each array. (the product of which, of course equals the desired value)
My 5.
[no name] 19-Apr-12 10:10am    
Thanks. In my example the array size is known at compile. If not as you say the size must be got another way at runtime. Not really a big deal.
Chuck O'Toole 19-Apr-12 10:11am    
Of course, this works and is efficient if memory size is no object. The original poster said the arrays were "large / very large" which makes for an interesting intellectual exercise. What if you cannot contain both arrays *and* the concatenated array in memory at the same time? The "sample" code posted showed statically allocated initial arrays so it's easy to ignore the "size" problem. The "large / very large" arrays are probably not entered as constants into the compiler. If we knew where those came from, it might generate a different solution.
Hm... :) :
C++
{
    int arSmallOwnerA[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    int arSmallOwnerB[] = { 1, 2, 3 };
    int* piConcatenation[_countof(arSmallOwnerA) + _countof(arSmallOwnerB) + 1] = { NULL };
 
    int i = 0;
    for( ;i < _countof(arSmallOwnerA); i++ )
    {
        piConcatenation[i] = &arSmallOwnerA[i];
    }
    for( int j =0; i < _countof(arSmallOwnerA) + _countof(arSmallOwnerB); i++, j++ )
    {
        piConcatenation[i] = &arSmallOwnerB[j];
    }
 
    for( int i = 0; i < _countof( piConcatenation ) - 1; i++ )
    {
	cout<< *(piConcatenation[i]) << endl;
    }
  }
 
Share this answer
 
v3
Comments
Resmi Anna 19-Apr-12 2:40am    
"Code Edition" not so bad I guess.....
Eugen Podsypalnikov 19-Apr-12 2:45am    
Thanks, 5-ed :)
Resmi Anna 19-Apr-12 2:53am    
:)
cammaratasergio 19-Apr-12 6:45am    
Thank you for your code! But I think that using cycles is a suboptimal solution.
Rather, I thought to implement the function by explicitly managing memory.
[no name] 19-Apr-12 8:20am    
No it isn't. It depends on the size of the arrays. You have posted a very generic question. For small arrays this method is fine. For large arrays memcpy is the only way. Provide specific information in your question and you will get better answers.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900