-2

I have an array:

unsigned char data[dataLength];

and a function:

unsigned char* get_data(int length)

I want to assign the return value of the function to the variable.

When I do it straight forward

data = get_data(length);

the compiler is complaining:

incompatible types in assignment of ‘unsigned char*’ to ‘unsigned char [(((sizetype)(((ssizetype)frameLength) + -1)) + 1)]’

It works with memcpy:

memcpy(data, get_data(dataLength), dataLength);

but I don't want to copy the data again.

Can someone help?

dju
  • 129
  • 4
  • 18
  • 1
    You seem to be making some mistakes copy/pasting your code. Is it `data` or `frame`? Is it `getData()` or `get_data()`? Please try instead to create a single self-contained example: [mcve]. – BoBTFish Aug 16 '18 at 06:51
  • yes of course, thanks. – dju Aug 16 '18 at 06:52
  • 1
    You can't avoid copying, `data` is not a pointer, but a buffer allocated on stack, you can't assign a pointer to it. – Evg Aug 16 '18 at 06:52
  • If it's C++, simply return `std::vector`. – HolyBlackCat Aug 16 '18 at 06:52
  • You can't assign to an array. Also, arrays are not pointers, and pointers are not arrays. Ask a new question about the problem you're trying to solve by doing this instead. (And ask about the language you're programming in. C and C++ are very different.) – molbdnilo Aug 16 '18 at 06:52
  • @HolyBlackCat In C you can simply return a struct too. A solution about as horrible. – Lundin Aug 16 '18 at 06:58
  • @Lundin What's so horrible about returning `std::vector`? (To clarify, I'm suggesting assigning the result to a vector as well, not copying it to an array.) – HolyBlackCat Aug 16 '18 at 07:24
  • @HolyBlackCat Because it relies on the compiler doing the correct optimizations to make up for the shortcomings of the language itself. – Lundin Aug 16 '18 at 08:17
  • This post can't be closed as a dupe to a C++ question unless the C and C++ tags are sorted out first. I re-opened it. – Lundin Aug 16 '18 at 08:21

2 Answers2

5

The way this is done in C is through parameter passing:

void get_data (int length, unsigned char data[length]);

call as:

get_data(dataLength, data);

data inside the function will now be the same object as the one allocated in the caller. No copies taken, no memcpy needed.

Lundin
  • 195,001
  • 40
  • 254
  • 396
2
  1. Your data is a stack allocated array. Though arrays decay to pointers when passed as function arguments, they are not pointers and you can't assign a pointer to it.
  2. It is not a good idea to return a raw pointer from a function like get_data(), because it is not clear who and how should free it.
  3. In C++ the easiest way would be to return either std::array<unsigned char, dataLength> if data size is known at compile time, or std::vector<unsigned char> otherwise. Then you don't have to worry about allocation, deallocation and using memcpy. If you want to reuse an existing buffer and avoid new allocation, pass it by non-const reference (see Lundin's answer).

// 1.
std::array<unsigned char, dataLength> get_data();
auto data = get_data();

// 2.
std::array<unsigned char, dataLength> data;
void get_data(std::array<unsigned char, dataLength>&);
get_data(data);

// 3.
std::vector<unsigned char> get_data(int length);
auto data = get_data(length);

// 4.
std::vector<unsigned char> data;
void get_data(std::vector<unsigned char>& data, int length);
get_data(data, length);
Evg
  • 25,259
  • 5
  • 41
  • 83