Вернуть массив из функции [дубликат]

141
25 декабря 2019, 21:30
This question already has answers here:
Как в С возвратить массив из функции? (2 ответа)
Как передать массив в функцию и вернуть его? (4 ответа)
Закрыт 9 месяцев назад.

Боюсь, что снова спрошу какую-то очевидную для всех вещь, которая для меня не очевидна: у меня есть функция, которая должна вернуть массив байт:

#pragma pack(1)
struct tube
{
  BYTE var1;    
  size_t var2;         
  BYTE  var3;    
};
#pragma pack()
tube* rez;
BYTE *MyFunc(){
    const unint sz = 6;
    BYTE replaced_origin[sz];
    for(int i =0;i<sz;i++) replaced_origin[i]=i;
    return replaced_origin;
}
rez = (tube*)MyFunc();

Я знаю, это не совсем верный подход. Во-первых в C++ не приветствуется возвращаться указатель на массив, поскольку его длина на выходе будет неизвестна и, принимая риски, я готов это сделать,т.к. в моем случае длина неизменна. Во вторых, насколько я понимаю, то строка BYTE replaced_origin[sz] выделила память под массив на стеке, а значит вне метода этот указатель станет невалидным?

Знаю, в C++ часто вместо массива используют vector для возврата из функции. Но мне кажется излишним создавать vector для 6-байтного массива, длина которого заведомо известна. Так же знаю, что можно воспользоваться new для выделения памяти в куче. Но память в куче выделяется медленнее, чем на стеке.

В общем, одним словом мне бы хотелось бы вернуть из функции массив путем копирования по значению, но - я новичек в с++ - никак не могу понять, как это правильно оформить

Answer 1

Если знаете точный размер во время компиляции - используйте std::array, если не знаете - strd::vector. Накладных расходов в первом случае никаких, во втором - минимальные, а вот плюсов очень много - не надо беспокоиться о всех проблемах владения.

Беспокоиться о том, сколько времени занимает выделение памяти, и сколько - копирование, будет потом, когда профайлер ясно покажет, что ваш затык именно в этом (во что лично я не верю - добро бы выделяли/освобождали память в каком-то особо быстром цикле, но вот так, разово?

Если вы любитель эффективности :) - создавайте массив вне функции, и передавайте внутрь указатель на него. Это быстрее и надежнее.

И еще - меня очень смущает, что вы работаете со структурой как с массивом байтов. Так ли уж это необходимо? Чем вот это хуже?

tube rez;
void MyFunc(tube * t)
{
    t->var1 = 0;
    t->var2 = 0x04030201;
    t->var3 = 0x05;
}
MyFunc(&rez);

Или это?

tube rez;
void MyFunc(tube & t)
{
    t.var1 = 0;
    t.var2 = 0x04030201;
    t.var3 = 0x05;
}
MyFunc(rez);
Answer 2

Если мы говорим о С++, самое простое:

struct tube
{
  BYTE var1 = 0x00;
  size_t var2 = 0x04030201;
  BYTE var2 = 0x05;
}
tube MyFunc()
{
  return tube();
}

Собственно, в этом случае, ценность самой функции - нулевая.

Answer 3

Если вам "кажется излишним создавать vector для 6-байтного массива, длина которого заведомо известна" и при этом не хочется создавать массив в динамической памяти, то есть еще один вариант. Объявите его как

static BYTE replaced_origin[sz];

и возвращайте его адрес на здоровье. Такой массив будет существовать все время выполнения программы. Вообще использование статических переменных без явной необходимости считается плохим стилем, но тем не менее это совершенно корректное решение.

READ ALSO
java.lang.String cannot be applied to LiveData&lt;java.lang.String&gt;. Как исправить?

java.lang.String cannot be applied to LiveData<java.lang.String>. Как исправить?

Что нужно сделать чтобы исправить эту ошибку? Firebase требует javalang

140
Получение Root прав Android

Получение Root прав Android

Мне необходимо получить Root права на андроидЯ знаю что есть много приложений , предназначенных для получения root, но в моем случае мне нужно...

126
Как узнать дату последнего смещения тем в Kafka?

Как узнать дату последнего смещения тем в Kafka?

У меня есть Kafka множеством топиковИ есть Consumer Kafka для чтения записей из этих тем:

111
Android: su pm install -r permission denied в системном приложении

Android: su pm install -r permission denied в системном приложении

Не могу обновить приложение без спроса пользователя, приложение является системным и вшито в прошивку в system/priv-app/Как пробовал:

137