2009-07-19 6 views

Répondre

4

Vous pouvez le faire avec un vecteur, parce que ses données sont stockées jointive:

std::vector<char> vec; 

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

Pour la liste, vous avez copier les données dans un tableau. Heureusement, cela aussi est assez facile:

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 

Bien sûr, vous êtes alors à gauche avec un tableau alloué dynamiquement vous devez libérer à nouveau.

+1

Il est probablement une bonne idée d'utiliser static_cast (list.size()) ou static_cast (vec.size()), étant donné que le résultat de la taille() est de type size_t qui pourrait ou non être convertible en int sur certaines plateformes. –

+1

Bonne réponse, +1. Mais pourquoi pas le meilleur des deux mondes - std :: copier vers un std :: vector ? – Reunanen

+0

D'accord avec Pukku, sauf que vous n'avez pas besoin de std :: copy dans le vecteur, utilisez le constructeur à deux itérateurs. –

0

list est une structure de données de liste chaînée. Il n'y a aucun moyen de le faire (théoriquement) sans conversion.

Vous pouvez accéder au (C++0x Draft 23.2.6.3) magasin de sauvegarde d'un vector avec .data() en C++ 0x. Actuellement, votre meilleur pari est de le traiter comme un tableau en prenant l'adresse de l'élément initial.

1

Vous pouvez le faire avec le vecteur, pas avec la liste. Un vecteur est garanti d'être un morceau Contigous de la mémoire afin que vous puissiez dire:

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

Je ne sais pas std :: liste, mais std :: vecteur ne:

std::vector<char> list_type; 

... 

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

std :: string peut faire le travail aussi, mais vous savez sans doute déjà.

1

Vous ne pouvez pas faire cela avec une liste, car une liste enregistre ses données dans des noeuds de liste. Cependant, vous pouvez le faire avec un vecteur, qui est garanti pour stocker ses données dans un morceau de mémoire contigu. Vous pouvez utiliser &v[0] ou &*v.begin() pour obtenir un pointeur vers son premier élément:

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

Notez que le vecteur libre arbitre automatiquement sa mémoire lorsque les fonctions de retour. Il y a (au moins) deux choses plus remarquables:

  • Le vecteur ne doit pas être vide. Vous n'êtes pas autorisé à accéder à v[0] d'un vecteur vide. (Vous n'êtes pas autorisé à déréférencer v.begin().)
  • Étant donné que l'allocation dynamique est impliquée, la conversion entre std::list et std::vector peut être un véritable tueur de performance. Envisager de passer à std::vector tout à fait.
Questions connexes