std :: list <char>list_type to (char * data, int длина) - PullRequest
2 голосов
/ 19 июля 2009

у меня есть

std::list<char> list_type

Теперь я должен предоставить содержимое списка в виде (char * data, int length). Есть ли удобный способ представить содержимое списка в виде указателя и длины? У <vector> есть такой интерфейс?

Спасибо заранее.

Ответы [ 5 ]

4 голосов
/ 19 июля 2009

Вы можете сделать это с вектором, потому что его данные хранятся непрерывно:

std::vector<char> vec;

char* data = &vec[0];
int length = static_cast<int>(vec.size());

Для списка вы должны скопировать данные в массив. К счастью, это тоже довольно просто:

std::list<char> list:
int length = static_cast<int>(list.size());
char* data = new char[length]; // create the output array
std::copy(list.begin(), list.end(), data); // copy the contents of the list to the output array

Конечно, вы получаете динамически распределенный массив, который нужно снова освободить.

1 голос
/ 20 июля 2009

Вы не можете сделать это со списком, поскольку список сохраняет свои данные в узлах списка. Тем не менее, вы можете сделать это с вектором, который гарантированно хранит свои данные в непрерывном фрагменте памяти. Вы можете использовать &v[0] или &*v.begin(), чтобы получить указатель на его первый элемент:

void f(std::list<char>& list)
{
  std::vector<char> vec(list.begin(),list.end());
  assert(!vec.empty());
  c_api_function(&vec[0],vec.size());
  // assuming you need the result of the call to replace the list's content
  list.assign(vec.begin(),vec.end());
}

Обратите внимание, что вектор автоматически освободит свою память, когда функция вернется. Есть (по крайней мере) еще две примечательные вещи:

  • Вектор не должен быть пустым. Вам не разрешен доступ к v[0] пустого вектора. (Вам также не разрешено разыменовывать v.begin().)
  • Поскольку используется динамическое распределение, преобразование между std::list и std::vector может привести к снижению производительности. Рассмотрите возможность переключения на std::vector в целом.
1 голос
/ 19 июля 2009

Я не знаю о std :: list, но std :: vector делает:

std::vector<char> list_type;

...

foo(&list_type[0], list_type.size())

std :: string тоже может выполнять эту работу, но вы, вероятно, уже знаете это.

1 голос
/ 19 июля 2009

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

char *data = &list_type[0];
std::vector<char>::size_type length = list_type.size();
0 голосов
/ 19 июля 2009

list - это структура данных связанного списка. Вы не можете сделать это (теоретически) без конвертации.

Вы сможете получить доступ ( C ++ 0x Draft 23.2.6.3 ) к резервному хранилищу vector с .data() в C ++ 0x. В настоящее время лучше всего рассматривать его как массив, используя адрес исходного элемента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...