динамический массив в структуре с последовательной памятью? - PullRequest
1 голос
/ 12 ноября 2011
struct Test
{
    int var;
    char *arr;
}

int main()
{
    Test a;
    a.arr = new char[50];
}

Приведенный выше код создаст динамический массив в структуре, но динамический массив не будет фактически памятью, выделенной в структуре, его память будет выделена где-то еще. Я хочу, чтобы этот массив был размещен в структуре как с фиксированным массивом, но я не хочу использовать фиксированный массив. Есть идеи? Я старался изо всех сил, чтобы уточнить мой вопрос, надеюсь, вы понимаете.

Я хочу отправить эту структуру через UDP, а UDP продолжает буферизацию памяти для отправки, поэтому я хочу, чтобы эта структура имела непрерывную память.

Ответы [ 7 ]

3 голосов
/ 12 ноября 2011

Вы не можете сделать это, так как новая память находится в куче / свободном хранилище, и ваш a будет выделен в стеке ...

вы можете выделить с помощью malloc / new непрерывный блок памяти размера Test+ требуемый размер и сделайте указатель arr для указания на конец структуры Test.

Если вам это нужно в области действия стека, вы можете использовать alloca.

Test *a = (Test*)alloca(sizeof(Test)+yoursize);
a->arr = (char*)a+sizeof(Test)...
1 голос
/ 12 ноября 2011

Нет, у вас не может быть массивов переменной длины в C ++.
Так что вы не можете этого сделать.

Вы можете иметь массив фиксированной длины или использовать предложенный вами подход.

Другой подход заключается в следующем:
Вы можете использовать размещение нового , чтобы разместить массив в заранее выделенном месте в памяти.Эта память может быть в стеке.

0 голосов
/ 12 ноября 2011

Не совсем динамическое распределение, но может решить вашу проблему (зависит от того, всегда ли вы знаете желаемый размер массива во время компиляции)

template <size_t ArraySize>
struct Test
{
    int var;
    char arr[ArraySize];
}

int main()
{
    Test<50> a;      
}
0 голосов
/ 12 ноября 2011

Несмотря на то, что он не был «благословен», как в C, большинство компиляторов по-прежнему позволяют использовать «struct hack»:

struct variable_array { 
    size_t size;
    char data[1];
};

«Хитрость» заключается в том, что когда вы выделяете его, вы выделяете достаточно места для данных, которые вы хотите сохранить (но это означает, что должно быть динамически выделено):

variable_array *a = (variable_array *) ::operator new(sizeof(*a) + data_size);
a->size = data_size;

Теоретически это не требуется для работы - компилятор может выполнить проверку ссылок на член data, чтобы убедиться, что вы не индексируете ни один элемент, который вы ' мы определили его для хранения в определении структуры. На самом деле, я не знаю ни одного компилятора, который бы делал такие вещи, и вроде бы сомневался, что такая вещь существует. Довольно много кода на C делал такие вещи годами, поэтому компилятор, который делал такую ​​проверку, просто не работал бы с большим количеством реального кода, даже если стандарт это допускает. C99 также добавляет это (с немного отличающимся синтаксисом) в качестве официальной функции языка.

Итог: это немного неуклюже, но возможность действительно не работать почти полностью теоретическая.

0 голосов
/ 12 ноября 2011

Вы можете передать размер массива конструктору структур и выделить там память для массива.Не забудьте освободить его где-нибудь, например, в деструкторе:

struct Test
{
    int m_var;
    char *arr;
public:
    Test(int var) : m_var(var)
    {
        arr = new char[m_var];
    }

    ~Test()
    {
        delete[] arr;
        arr = 0;
    }
};

void main(int argc, char* argv[])
{
   Test t(50);
   return 0;
}
0 голосов
/ 12 ноября 2011
struct Test {
  int var;
  char arr[1];
};

int main()
{
    std::vector<char> buf;
    buf.resize(sizeof(Test) + 50);
    Test *foo = reinterpret_cast<Test *>(&buf[0]);
    foo->arr[40] = 'b';
}
0 голосов
/ 12 ноября 2011

Ваш код не компилируется.Вы должны скомпилировать его со всеми включенными предупреждениями и улучшать его, пока не получите никаких предупреждений.И вы изучаете C или C ++?Если это C ++, рассмотрите возможность использования std :: vector

...