Forum Programmation.c++ probleme de compréhension sur les rvalue et std::move

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
0
14
jan.
2022

bonjours à tous,

Dans le code ci-dessous, j'ai l'impression que la lvalue est copié au lieu d'etre déplacé car le pointeur ou se trouve la chaine de caractere "Salut" n'est plus la meme avant et apres le std::move
voici mon code :

std::string str = "Salut";
std::vector<std::string> v;

std::cout << "str.data() = " << (void*)str.data() << "; str.size() = " << str.size() << " ; str = " << str  << std::endl;
//renvoie str.data() = 0x7ffcce8b6560; str.size() = 5 ; str = Salut

const char * pStr = str.data();
printf("myPrintf = %s\n", pStr); // renvoie Salut

v.push_back(std::move(str));

std::cout << "v[0].data() = " << (void*)v[0].data() << "; v[1] = " << v[1] << std::endl;
//renvoie v[1].data() = 0x562d71ada2e0; v[1] = Salut

pStr = str.data();//renvoie str.data() = 0x7ffcce8b6560; str.size() = 0 ; str =
printf("myPrintf = %s\n", pStr); //renvoie myPrintf =

On voit bien que str n'existe plus, mais n'a rien a été déplacé, il y a eu copie. Je comprend vraiment pas l'utilité des lvalue

Merci d'avance pour vos éclaircissements :)

  • # Erreur ?

    Posté par  . Évalué à 2. Dernière modification le 14 janvier 2022 à 15:55.

    Salut, je vais sans doute écrire des bêtises…
    dans la dernière partie tu utilises V[1] alors qu’il n’y a que l’élément 0.

    Si a la place de ….data() tu utilises ….c_str() ? Ça change quelque chose ? (normalement non.)

    Après, le move est fait pour éviter des grosses copies, ici on peut copier avec juste une copie de 64bits. Avec une très longue chaîne, c’est pareil ?

    Le push_back doit également allouer la mémoire, si tu fait un vector.resize(8) avant le push_back, est-ce que ça se comporte pareil ?

    Pas d’idée supplémentaire.

  • # attention,

    Posté par  . Évalué à 3.

    avec des string, tu va tomber sur la sso (short string optimisation), si ta chaîne est plus courte qu'un pointeur, il n'y a pas d'allocation dynamique; et donc ça va pointer sur l'objet lui même.

    Il vaut mieux tester avec une chaîne de plus de 64 octets.

    Ensuite comme dit plus haut tu va taper la case 1 du vecteur, qui n'a qu'un seul élément tu risque le segfault

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

    • [^] # Re: attention,

      Posté par  (site web personnel) . Évalué à 3.

      Il vaut mieux tester avec une chaîne de plus de 64 octets.

      plus de 22 suffira.
      Sur machine 64-bit : 8 octets par champs * 3 champs (début, taille, fin/taille allouée) - le 0 terminal - 1 octet pour la taille en cas de SSO.

  • # SSO Optimisation

    Posté par  . Évalué à 2.

    Depuis le passage à C++11 (si je ne dis pas de bêtises) et le cassage d'ABI qui va avec, la norme impose aux std::string l'optimisation SSO (Small String Optimisation),
    En gros, l'implémentation "classique" du stockage de l'information dans une std::string ressemble fortement à celle d'un std::vector, un pointer pour le début, un pour la fin de la string et un pour la fin de la zone allouée.
    ça fait donc 3 pointeurs, et en 64 bits, 24 octets donc.
    Du coup au lieu d'allouer de l'espace mémoire pour les petites strings (moins de 23 octet pour garder le 0 terminal), on peut simplement se servir de ces 24 octets pour mettre la donnée "directement"
    Pour ces petites string le temps de la copie est négligeable par rapport au temps d'allocation et en particulier c'est thread-safe par rapport à un std::move.
    Voila pourquoi SSO est maintenant le standard pour les std::string.

    PS: l'implémentation est un peu plus compliquée que cela, du coup c'est un peu moins de 23 octets, tu peux essayer de faire des tests pour voir à partir de quand le comportement change.

  • # tout marche

    Posté par  . Évalué à 2.

    oui j'ai augmenté la taille du string et le systeme de rvalue a bien donné l'adresse ou se trouve la chaine de caractere, et n'a donc pas fait de copy

    merci beaucoup pour vos éclaircissements

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.