BaruchLi
BaruchLi

Reputation: 1103

std::list<char> list_type to (char * data, int lenght)

I have some

std::list<char> list_type

Now I have to supply contents of the list as (char *data, int length). Is there convenient way to present list contents as pointer and length? Does <vector> has such interface?

Thank you in advance.

Upvotes: 2

Views: 5685

Answers (5)

sbi
sbi

Reputation: 224089

You cannot do this with a list, as a list saves its data in list nodes. However, you can do this with a vector, which is guaranteed to store its data in a contiguous piece of memory. You can use either &v[0] or &*v.begin() to get a pointer to its first element:

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());
}

Note that the vector will automatically free its memory when the function returns. There are (at least) two more noteworthy things:

  • The vector must not be empty. You are not allowed to access v[0] of an empty vector. (Neither are you allowed to dereference v.begin().)
  • Since dynamic allocation is involved, converting back and forth between std::list and std::vector can be a real performance killer. Consider switching to std::vector altogether.

Upvotes: 1

Stack Overflow is garbage
Stack Overflow is garbage

Reputation: 247999

You can do it with a vector, because its data is stored contiguously:

std::vector<char> vec;

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

For list, you have to copy the data to an array. Luckily, that too is fairly easy:

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

Of course, you're then left with a dynamically allocated array you have to free again.

Upvotes: 4

Mehrdad Afshari
Mehrdad Afshari

Reputation: 422016

list is a linked list data structure. There's no way you could do that (theoretically) without conversion.

You'll be able to access (C++0x Draft 23.2.6.3) the backing store of a vector with .data() in C++0x. Currently, your best bet is to treat it as an array by taking the address of the initial element.

Upvotes: 0

dimba
dimba

Reputation: 27581

I don't know about std::list, but std::vector does:

std::vector<char> list_type;

...

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

std::string can do the job too, but you probably already know it.

Upvotes: 1

Logan Capaldo
Logan Capaldo

Reputation: 40336

You can do this with vector, not with list. A vector is guaranteed to be a contigous chunk of memory so you can say:

char *data = &list_type[0];
std::vector<char>::size_type length = list_type.size();

Upvotes: 1

Related Questions