Is std::string guaranteed not to give back memory spontaneously?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
28
down vote

favorite
3












Is it guaranteed by the standard that std::string will not give back allocated memory spontaneously if reassigned from a string of a smaller size?



In other words:



std::string str = "Some quite long string, which needs a lot of memory";
str = "";
str = "A new quite long but smaller string"; // Guaranteed to not result in a heap allocation?


I ask because i'm depending on this to avoid heap fragmentation.










share|improve this question























  • if the new string allocation is less than the previous allocation, no allocation occurs. If the new string requires more allocation than the current, a reallocation occurs. Similar to a std::vector.
    – Samer Tufail
    Sep 25 at 10:19










  • Strings reuse their buffers when assigned to shorter strings, so in your program there is only one allocation for the string. Unfortunately I can't find conveniently any citation from the standard on mobile
    – Fureeish
    Sep 25 at 10:20






  • 1




    Even if a string did "give back memory spontaneously", that is insufficient to avoid heap fragmentation. A string uses an allocator (by default, an object of type std::allocator<char>, but that can be changed) to allocate and deallocate memory, and the allocator may use a lower-level mechanism again (e.g. variants of operators new and delete) to actually allocate and deallocate. If any of those steps elect to not release memory to the lower-level layer, there is potential impact on heap fragmentation.
    – Peter
    Sep 25 at 10:34






  • 2




    If you need to guarantee this behaviour, you can always used your own custom allocator
    – doron
    Sep 25 at 12:26






  • 10




    In my own experience, if I have to utter the phrase "I'm dependent on avoiding heap fragmentation," its a very good time to start considering identifying precise low level requirements, and potentially rolling your own allocation routines.
    – Cort Ammon
    Sep 25 at 18:06














up vote
28
down vote

favorite
3












Is it guaranteed by the standard that std::string will not give back allocated memory spontaneously if reassigned from a string of a smaller size?



In other words:



std::string str = "Some quite long string, which needs a lot of memory";
str = "";
str = "A new quite long but smaller string"; // Guaranteed to not result in a heap allocation?


I ask because i'm depending on this to avoid heap fragmentation.










share|improve this question























  • if the new string allocation is less than the previous allocation, no allocation occurs. If the new string requires more allocation than the current, a reallocation occurs. Similar to a std::vector.
    – Samer Tufail
    Sep 25 at 10:19










  • Strings reuse their buffers when assigned to shorter strings, so in your program there is only one allocation for the string. Unfortunately I can't find conveniently any citation from the standard on mobile
    – Fureeish
    Sep 25 at 10:20






  • 1




    Even if a string did "give back memory spontaneously", that is insufficient to avoid heap fragmentation. A string uses an allocator (by default, an object of type std::allocator<char>, but that can be changed) to allocate and deallocate memory, and the allocator may use a lower-level mechanism again (e.g. variants of operators new and delete) to actually allocate and deallocate. If any of those steps elect to not release memory to the lower-level layer, there is potential impact on heap fragmentation.
    – Peter
    Sep 25 at 10:34






  • 2




    If you need to guarantee this behaviour, you can always used your own custom allocator
    – doron
    Sep 25 at 12:26






  • 10




    In my own experience, if I have to utter the phrase "I'm dependent on avoiding heap fragmentation," its a very good time to start considering identifying precise low level requirements, and potentially rolling your own allocation routines.
    – Cort Ammon
    Sep 25 at 18:06












up vote
28
down vote

favorite
3









up vote
28
down vote

favorite
3






3





Is it guaranteed by the standard that std::string will not give back allocated memory spontaneously if reassigned from a string of a smaller size?



In other words:



std::string str = "Some quite long string, which needs a lot of memory";
str = "";
str = "A new quite long but smaller string"; // Guaranteed to not result in a heap allocation?


I ask because i'm depending on this to avoid heap fragmentation.










share|improve this question















Is it guaranteed by the standard that std::string will not give back allocated memory spontaneously if reassigned from a string of a smaller size?



In other words:



std::string str = "Some quite long string, which needs a lot of memory";
str = "";
str = "A new quite long but smaller string"; // Guaranteed to not result in a heap allocation?


I ask because i'm depending on this to avoid heap fragmentation.







c++ language-lawyer heap-memory stdstring






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Sep 25 at 10:57









underscore_d

2,97831842




2,97831842










asked Sep 25 at 10:13









Martin G

8,92465361




8,92465361











  • if the new string allocation is less than the previous allocation, no allocation occurs. If the new string requires more allocation than the current, a reallocation occurs. Similar to a std::vector.
    – Samer Tufail
    Sep 25 at 10:19










  • Strings reuse their buffers when assigned to shorter strings, so in your program there is only one allocation for the string. Unfortunately I can't find conveniently any citation from the standard on mobile
    – Fureeish
    Sep 25 at 10:20






  • 1




    Even if a string did "give back memory spontaneously", that is insufficient to avoid heap fragmentation. A string uses an allocator (by default, an object of type std::allocator<char>, but that can be changed) to allocate and deallocate memory, and the allocator may use a lower-level mechanism again (e.g. variants of operators new and delete) to actually allocate and deallocate. If any of those steps elect to not release memory to the lower-level layer, there is potential impact on heap fragmentation.
    – Peter
    Sep 25 at 10:34






  • 2




    If you need to guarantee this behaviour, you can always used your own custom allocator
    – doron
    Sep 25 at 12:26






  • 10




    In my own experience, if I have to utter the phrase "I'm dependent on avoiding heap fragmentation," its a very good time to start considering identifying precise low level requirements, and potentially rolling your own allocation routines.
    – Cort Ammon
    Sep 25 at 18:06
















  • if the new string allocation is less than the previous allocation, no allocation occurs. If the new string requires more allocation than the current, a reallocation occurs. Similar to a std::vector.
    – Samer Tufail
    Sep 25 at 10:19










  • Strings reuse their buffers when assigned to shorter strings, so in your program there is only one allocation for the string. Unfortunately I can't find conveniently any citation from the standard on mobile
    – Fureeish
    Sep 25 at 10:20






  • 1




    Even if a string did "give back memory spontaneously", that is insufficient to avoid heap fragmentation. A string uses an allocator (by default, an object of type std::allocator<char>, but that can be changed) to allocate and deallocate memory, and the allocator may use a lower-level mechanism again (e.g. variants of operators new and delete) to actually allocate and deallocate. If any of those steps elect to not release memory to the lower-level layer, there is potential impact on heap fragmentation.
    – Peter
    Sep 25 at 10:34






  • 2




    If you need to guarantee this behaviour, you can always used your own custom allocator
    – doron
    Sep 25 at 12:26






  • 10




    In my own experience, if I have to utter the phrase "I'm dependent on avoiding heap fragmentation," its a very good time to start considering identifying precise low level requirements, and potentially rolling your own allocation routines.
    – Cort Ammon
    Sep 25 at 18:06















if the new string allocation is less than the previous allocation, no allocation occurs. If the new string requires more allocation than the current, a reallocation occurs. Similar to a std::vector.
– Samer Tufail
Sep 25 at 10:19




if the new string allocation is less than the previous allocation, no allocation occurs. If the new string requires more allocation than the current, a reallocation occurs. Similar to a std::vector.
– Samer Tufail
Sep 25 at 10:19












Strings reuse their buffers when assigned to shorter strings, so in your program there is only one allocation for the string. Unfortunately I can't find conveniently any citation from the standard on mobile
– Fureeish
Sep 25 at 10:20




Strings reuse their buffers when assigned to shorter strings, so in your program there is only one allocation for the string. Unfortunately I can't find conveniently any citation from the standard on mobile
– Fureeish
Sep 25 at 10:20




1




1




Even if a string did "give back memory spontaneously", that is insufficient to avoid heap fragmentation. A string uses an allocator (by default, an object of type std::allocator<char>, but that can be changed) to allocate and deallocate memory, and the allocator may use a lower-level mechanism again (e.g. variants of operators new and delete) to actually allocate and deallocate. If any of those steps elect to not release memory to the lower-level layer, there is potential impact on heap fragmentation.
– Peter
Sep 25 at 10:34




Even if a string did "give back memory spontaneously", that is insufficient to avoid heap fragmentation. A string uses an allocator (by default, an object of type std::allocator<char>, but that can be changed) to allocate and deallocate memory, and the allocator may use a lower-level mechanism again (e.g. variants of operators new and delete) to actually allocate and deallocate. If any of those steps elect to not release memory to the lower-level layer, there is potential impact on heap fragmentation.
– Peter
Sep 25 at 10:34




2




2




If you need to guarantee this behaviour, you can always used your own custom allocator
– doron
Sep 25 at 12:26




If you need to guarantee this behaviour, you can always used your own custom allocator
– doron
Sep 25 at 12:26




10




10




In my own experience, if I have to utter the phrase "I'm dependent on avoiding heap fragmentation," its a very good time to start considering identifying precise low level requirements, and potentially rolling your own allocation routines.
– Cort Ammon
Sep 25 at 18:06




In my own experience, if I have to utter the phrase "I'm dependent on avoiding heap fragmentation," its a very good time to start considering identifying precise low level requirements, and potentially rolling your own allocation routines.
– Cort Ammon
Sep 25 at 18:06












4 Answers
4






active

oldest

votes

















up vote
34
down vote



accepted










No guarantee whatsoever.



[string.cons]/36 defines assigning a const char* to an std::string in term of a move-assignment, whose definition is:




[string.cons]/32



basic_string& operator=(basic_string&& str) noexcept(/*...*/)


Effects: Move assigns as a sequence container, except that iterators, pointers and references may be invalidated.




This shows that the Committee let the implementation choose freely between an invalidating operation and a more conservative one. And to make things even clearer:




[basic.string]/4



References, pointers, and iterators referring to the elements of a basic_­string sequence may be invalidated by the following uses of that basic_­string object:



  • (4.1) as an argument to any standard library function taking a reference to non-const basic_­string as an argument.

  • (4.2) Calling non-const member functions, except operator, at, data, front, back, begin, rbegin, end, and rend.





I ask because i'm depending on this to avoid heap fragmentation.




std::string takes as template-parameter an allocator. If you're really concerned by a possible heap fragmentation, you could write your own, which with some heuristics could have an allocation strategy suited for your needs.



In practice, most implementations I know of would not reallocate memory in the case of your question. This can be checked by testing and/or checking your implementation doc and eventually source code.






share|improve this answer


















  • 4




    You can imagine how undesirable such a guarantee would be (presuming it was given), if you had the Gettysburg Address stored in a string, and then replaced it with "Hello World."
    – Cort Ammon
    Sep 25 at 18:28

















up vote
12
down vote













CPP reference states that assignment to a pointer-to-char




Replaces the contents with those of null-terminated character string pointed to by s as if by *this = basic_string(s), which involves a call to Traits::length(s).




This "as if" actually boils down to an rvalue assignment, so the following scenario is quite possible:



  1. A fresh temporary string is created.


  2. This string steals its contents as via assignment to an rvalue reference.





share|improve this answer


















  • 3




    cppreference is usually reliable, but the quoted statement implies that there is a guaranteed buffer replacement, which is bollocks. Other than that it's a good conceptual model. But it's just marginally simpler than the standard's description, quoted in YSC's answer, which would therefore be preferable.
    – Cheers and hth. - Alf
    Sep 25 at 10:34







  • 5




    @Cheersandhth.-Alf cppreference is paraphrasing the standard [string.cons]
    – Caleth
    Sep 25 at 10:39






  • 4




    @Cheersandhth.-Alf Does it really? It says "as if", which, in Standard, always means "with regard to observable side effects, aside from few those of constructions/destructions".
    – bipll
    Sep 25 at 10:46










  • @rustyx it's allowed to do either. You can conceptualise it as the temporary stealing the existing allocation, then returning it.
    – Caleth
    Sep 25 at 12:01






  • 1




    @rustyx The standard just talks about the effect. Given that the effect of x = "hi"; is the same as the effect of x.assign("hi");, an implementation would do the efficient thing for both. libstdc++, for instance, has its operator=(const CharT*) just directly call assign
    – Barry
    Sep 25 at 13:40

















up vote
3
down vote














Is it guaranteed by the standard that std::string will not give back allocated memory spontaneously if reassigned from a string of a smaller size?




Regardless of the actual answer (which is "No, no guarantee") - you should employ the following principle: If it's not obvious that it has to be the case, then don't assume it is the case.



In your specific case - if you want tight control of heap behavior, you might not even want to use std::strings at all (maybe; it depends). And you might not want to use the default allocator (again, maybe); and you might want to memoize strings; etc. What you should absolutely do is make fewer assumptions, measure if possible, and have explicit design to ensure your needs are met.






share|improve this answer





























    up vote
    2
    down vote













    If your strings are short (up to 15 or 22 bytes, depending on the compiler/std lib) and you are using a relatively recent compiler in C++11 or later mode, then you are likely to benefit from the Short String Optimization (SSO). In this case the string contents are not separately allocated on the heap.



    This link also contains a lot of details on common implementations and allocation strategies.



    However, both of the strings in your example are too long for SSO.






    share|improve this answer




















    • Is it guaranteed by the standard? Is SSO guaranteed by the standard?
      – pipe
      Sep 26 at 0:40










    • @pipe No it isn't, what Paul implied in: "you are likely to benefit from the Short String Optimization (SSO)".
      – YSC
      Sep 26 at 7:17










    • @YSC Ok, but the question is rather specific, and OP already knows that it is likely to happen since he depends on it, so I don't understand what this actually answers.
      – pipe
      Sep 26 at 8:27










    • @pipe I agree this answer is slightly off, but it was answered right after OP asked their question. The question wasn't tagged language-lawyer at that time, and get edited after that. This is answering part of OP concern (mem frag) and provides an interesting insight. I've upvoted it for what it's worth.
      – YSC
      Sep 26 at 9:44











    • It's not meant to be a full answer, just a complement for the case of SSO. I think that the link is quite interesting regarding practical measures of std::string performance.
      – Paul Floyd
      Sep 26 at 10:52










    Your Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52495704%2fis-stdstring-guaranteed-not-to-give-back-memory-spontaneously%23new-answer', 'question_page');

    );

    Post as a guest






























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    34
    down vote



    accepted










    No guarantee whatsoever.



    [string.cons]/36 defines assigning a const char* to an std::string in term of a move-assignment, whose definition is:




    [string.cons]/32



    basic_string& operator=(basic_string&& str) noexcept(/*...*/)


    Effects: Move assigns as a sequence container, except that iterators, pointers and references may be invalidated.




    This shows that the Committee let the implementation choose freely between an invalidating operation and a more conservative one. And to make things even clearer:




    [basic.string]/4



    References, pointers, and iterators referring to the elements of a basic_­string sequence may be invalidated by the following uses of that basic_­string object:



    • (4.1) as an argument to any standard library function taking a reference to non-const basic_­string as an argument.

    • (4.2) Calling non-const member functions, except operator, at, data, front, back, begin, rbegin, end, and rend.





    I ask because i'm depending on this to avoid heap fragmentation.




    std::string takes as template-parameter an allocator. If you're really concerned by a possible heap fragmentation, you could write your own, which with some heuristics could have an allocation strategy suited for your needs.



    In practice, most implementations I know of would not reallocate memory in the case of your question. This can be checked by testing and/or checking your implementation doc and eventually source code.






    share|improve this answer


















    • 4




      You can imagine how undesirable such a guarantee would be (presuming it was given), if you had the Gettysburg Address stored in a string, and then replaced it with "Hello World."
      – Cort Ammon
      Sep 25 at 18:28














    up vote
    34
    down vote



    accepted










    No guarantee whatsoever.



    [string.cons]/36 defines assigning a const char* to an std::string in term of a move-assignment, whose definition is:




    [string.cons]/32



    basic_string& operator=(basic_string&& str) noexcept(/*...*/)


    Effects: Move assigns as a sequence container, except that iterators, pointers and references may be invalidated.




    This shows that the Committee let the implementation choose freely between an invalidating operation and a more conservative one. And to make things even clearer:




    [basic.string]/4



    References, pointers, and iterators referring to the elements of a basic_­string sequence may be invalidated by the following uses of that basic_­string object:



    • (4.1) as an argument to any standard library function taking a reference to non-const basic_­string as an argument.

    • (4.2) Calling non-const member functions, except operator, at, data, front, back, begin, rbegin, end, and rend.





    I ask because i'm depending on this to avoid heap fragmentation.




    std::string takes as template-parameter an allocator. If you're really concerned by a possible heap fragmentation, you could write your own, which with some heuristics could have an allocation strategy suited for your needs.



    In practice, most implementations I know of would not reallocate memory in the case of your question. This can be checked by testing and/or checking your implementation doc and eventually source code.






    share|improve this answer


















    • 4




      You can imagine how undesirable such a guarantee would be (presuming it was given), if you had the Gettysburg Address stored in a string, and then replaced it with "Hello World."
      – Cort Ammon
      Sep 25 at 18:28












    up vote
    34
    down vote



    accepted







    up vote
    34
    down vote



    accepted






    No guarantee whatsoever.



    [string.cons]/36 defines assigning a const char* to an std::string in term of a move-assignment, whose definition is:




    [string.cons]/32



    basic_string& operator=(basic_string&& str) noexcept(/*...*/)


    Effects: Move assigns as a sequence container, except that iterators, pointers and references may be invalidated.




    This shows that the Committee let the implementation choose freely between an invalidating operation and a more conservative one. And to make things even clearer:




    [basic.string]/4



    References, pointers, and iterators referring to the elements of a basic_­string sequence may be invalidated by the following uses of that basic_­string object:



    • (4.1) as an argument to any standard library function taking a reference to non-const basic_­string as an argument.

    • (4.2) Calling non-const member functions, except operator, at, data, front, back, begin, rbegin, end, and rend.





    I ask because i'm depending on this to avoid heap fragmentation.




    std::string takes as template-parameter an allocator. If you're really concerned by a possible heap fragmentation, you could write your own, which with some heuristics could have an allocation strategy suited for your needs.



    In practice, most implementations I know of would not reallocate memory in the case of your question. This can be checked by testing and/or checking your implementation doc and eventually source code.






    share|improve this answer














    No guarantee whatsoever.



    [string.cons]/36 defines assigning a const char* to an std::string in term of a move-assignment, whose definition is:




    [string.cons]/32



    basic_string& operator=(basic_string&& str) noexcept(/*...*/)


    Effects: Move assigns as a sequence container, except that iterators, pointers and references may be invalidated.




    This shows that the Committee let the implementation choose freely between an invalidating operation and a more conservative one. And to make things even clearer:




    [basic.string]/4



    References, pointers, and iterators referring to the elements of a basic_­string sequence may be invalidated by the following uses of that basic_­string object:



    • (4.1) as an argument to any standard library function taking a reference to non-const basic_­string as an argument.

    • (4.2) Calling non-const member functions, except operator, at, data, front, back, begin, rbegin, end, and rend.





    I ask because i'm depending on this to avoid heap fragmentation.




    std::string takes as template-parameter an allocator. If you're really concerned by a possible heap fragmentation, you could write your own, which with some heuristics could have an allocation strategy suited for your needs.



    In practice, most implementations I know of would not reallocate memory in the case of your question. This can be checked by testing and/or checking your implementation doc and eventually source code.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 28 at 11:23

























    answered Sep 25 at 10:18









    YSC

    18k34187




    18k34187







    • 4




      You can imagine how undesirable such a guarantee would be (presuming it was given), if you had the Gettysburg Address stored in a string, and then replaced it with "Hello World."
      – Cort Ammon
      Sep 25 at 18:28












    • 4




      You can imagine how undesirable such a guarantee would be (presuming it was given), if you had the Gettysburg Address stored in a string, and then replaced it with "Hello World."
      – Cort Ammon
      Sep 25 at 18:28







    4




    4




    You can imagine how undesirable such a guarantee would be (presuming it was given), if you had the Gettysburg Address stored in a string, and then replaced it with "Hello World."
    – Cort Ammon
    Sep 25 at 18:28




    You can imagine how undesirable such a guarantee would be (presuming it was given), if you had the Gettysburg Address stored in a string, and then replaced it with "Hello World."
    – Cort Ammon
    Sep 25 at 18:28












    up vote
    12
    down vote













    CPP reference states that assignment to a pointer-to-char




    Replaces the contents with those of null-terminated character string pointed to by s as if by *this = basic_string(s), which involves a call to Traits::length(s).




    This "as if" actually boils down to an rvalue assignment, so the following scenario is quite possible:



    1. A fresh temporary string is created.


    2. This string steals its contents as via assignment to an rvalue reference.





    share|improve this answer


















    • 3




      cppreference is usually reliable, but the quoted statement implies that there is a guaranteed buffer replacement, which is bollocks. Other than that it's a good conceptual model. But it's just marginally simpler than the standard's description, quoted in YSC's answer, which would therefore be preferable.
      – Cheers and hth. - Alf
      Sep 25 at 10:34







    • 5




      @Cheersandhth.-Alf cppreference is paraphrasing the standard [string.cons]
      – Caleth
      Sep 25 at 10:39






    • 4




      @Cheersandhth.-Alf Does it really? It says "as if", which, in Standard, always means "with regard to observable side effects, aside from few those of constructions/destructions".
      – bipll
      Sep 25 at 10:46










    • @rustyx it's allowed to do either. You can conceptualise it as the temporary stealing the existing allocation, then returning it.
      – Caleth
      Sep 25 at 12:01






    • 1




      @rustyx The standard just talks about the effect. Given that the effect of x = "hi"; is the same as the effect of x.assign("hi");, an implementation would do the efficient thing for both. libstdc++, for instance, has its operator=(const CharT*) just directly call assign
      – Barry
      Sep 25 at 13:40














    up vote
    12
    down vote













    CPP reference states that assignment to a pointer-to-char




    Replaces the contents with those of null-terminated character string pointed to by s as if by *this = basic_string(s), which involves a call to Traits::length(s).




    This "as if" actually boils down to an rvalue assignment, so the following scenario is quite possible:



    1. A fresh temporary string is created.


    2. This string steals its contents as via assignment to an rvalue reference.





    share|improve this answer


















    • 3




      cppreference is usually reliable, but the quoted statement implies that there is a guaranteed buffer replacement, which is bollocks. Other than that it's a good conceptual model. But it's just marginally simpler than the standard's description, quoted in YSC's answer, which would therefore be preferable.
      – Cheers and hth. - Alf
      Sep 25 at 10:34







    • 5




      @Cheersandhth.-Alf cppreference is paraphrasing the standard [string.cons]
      – Caleth
      Sep 25 at 10:39






    • 4




      @Cheersandhth.-Alf Does it really? It says "as if", which, in Standard, always means "with regard to observable side effects, aside from few those of constructions/destructions".
      – bipll
      Sep 25 at 10:46










    • @rustyx it's allowed to do either. You can conceptualise it as the temporary stealing the existing allocation, then returning it.
      – Caleth
      Sep 25 at 12:01






    • 1




      @rustyx The standard just talks about the effect. Given that the effect of x = "hi"; is the same as the effect of x.assign("hi");, an implementation would do the efficient thing for both. libstdc++, for instance, has its operator=(const CharT*) just directly call assign
      – Barry
      Sep 25 at 13:40












    up vote
    12
    down vote










    up vote
    12
    down vote









    CPP reference states that assignment to a pointer-to-char




    Replaces the contents with those of null-terminated character string pointed to by s as if by *this = basic_string(s), which involves a call to Traits::length(s).




    This "as if" actually boils down to an rvalue assignment, so the following scenario is quite possible:



    1. A fresh temporary string is created.


    2. This string steals its contents as via assignment to an rvalue reference.





    share|improve this answer














    CPP reference states that assignment to a pointer-to-char




    Replaces the contents with those of null-terminated character string pointed to by s as if by *this = basic_string(s), which involves a call to Traits::length(s).




    This "as if" actually boils down to an rvalue assignment, so the following scenario is quite possible:



    1. A fresh temporary string is created.


    2. This string steals its contents as via assignment to an rvalue reference.






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Sep 25 at 13:12

























    answered Sep 25 at 10:19









    bipll

    7,3171824




    7,3171824







    • 3




      cppreference is usually reliable, but the quoted statement implies that there is a guaranteed buffer replacement, which is bollocks. Other than that it's a good conceptual model. But it's just marginally simpler than the standard's description, quoted in YSC's answer, which would therefore be preferable.
      – Cheers and hth. - Alf
      Sep 25 at 10:34







    • 5




      @Cheersandhth.-Alf cppreference is paraphrasing the standard [string.cons]
      – Caleth
      Sep 25 at 10:39






    • 4




      @Cheersandhth.-Alf Does it really? It says "as if", which, in Standard, always means "with regard to observable side effects, aside from few those of constructions/destructions".
      – bipll
      Sep 25 at 10:46










    • @rustyx it's allowed to do either. You can conceptualise it as the temporary stealing the existing allocation, then returning it.
      – Caleth
      Sep 25 at 12:01






    • 1




      @rustyx The standard just talks about the effect. Given that the effect of x = "hi"; is the same as the effect of x.assign("hi");, an implementation would do the efficient thing for both. libstdc++, for instance, has its operator=(const CharT*) just directly call assign
      – Barry
      Sep 25 at 13:40












    • 3




      cppreference is usually reliable, but the quoted statement implies that there is a guaranteed buffer replacement, which is bollocks. Other than that it's a good conceptual model. But it's just marginally simpler than the standard's description, quoted in YSC's answer, which would therefore be preferable.
      – Cheers and hth. - Alf
      Sep 25 at 10:34







    • 5




      @Cheersandhth.-Alf cppreference is paraphrasing the standard [string.cons]
      – Caleth
      Sep 25 at 10:39






    • 4




      @Cheersandhth.-Alf Does it really? It says "as if", which, in Standard, always means "with regard to observable side effects, aside from few those of constructions/destructions".
      – bipll
      Sep 25 at 10:46










    • @rustyx it's allowed to do either. You can conceptualise it as the temporary stealing the existing allocation, then returning it.
      – Caleth
      Sep 25 at 12:01






    • 1




      @rustyx The standard just talks about the effect. Given that the effect of x = "hi"; is the same as the effect of x.assign("hi");, an implementation would do the efficient thing for both. libstdc++, for instance, has its operator=(const CharT*) just directly call assign
      – Barry
      Sep 25 at 13:40







    3




    3




    cppreference is usually reliable, but the quoted statement implies that there is a guaranteed buffer replacement, which is bollocks. Other than that it's a good conceptual model. But it's just marginally simpler than the standard's description, quoted in YSC's answer, which would therefore be preferable.
    – Cheers and hth. - Alf
    Sep 25 at 10:34





    cppreference is usually reliable, but the quoted statement implies that there is a guaranteed buffer replacement, which is bollocks. Other than that it's a good conceptual model. But it's just marginally simpler than the standard's description, quoted in YSC's answer, which would therefore be preferable.
    – Cheers and hth. - Alf
    Sep 25 at 10:34





    5




    5




    @Cheersandhth.-Alf cppreference is paraphrasing the standard [string.cons]
    – Caleth
    Sep 25 at 10:39




    @Cheersandhth.-Alf cppreference is paraphrasing the standard [string.cons]
    – Caleth
    Sep 25 at 10:39




    4




    4




    @Cheersandhth.-Alf Does it really? It says "as if", which, in Standard, always means "with regard to observable side effects, aside from few those of constructions/destructions".
    – bipll
    Sep 25 at 10:46




    @Cheersandhth.-Alf Does it really? It says "as if", which, in Standard, always means "with regard to observable side effects, aside from few those of constructions/destructions".
    – bipll
    Sep 25 at 10:46












    @rustyx it's allowed to do either. You can conceptualise it as the temporary stealing the existing allocation, then returning it.
    – Caleth
    Sep 25 at 12:01




    @rustyx it's allowed to do either. You can conceptualise it as the temporary stealing the existing allocation, then returning it.
    – Caleth
    Sep 25 at 12:01




    1




    1




    @rustyx The standard just talks about the effect. Given that the effect of x = "hi"; is the same as the effect of x.assign("hi");, an implementation would do the efficient thing for both. libstdc++, for instance, has its operator=(const CharT*) just directly call assign
    – Barry
    Sep 25 at 13:40




    @rustyx The standard just talks about the effect. Given that the effect of x = "hi"; is the same as the effect of x.assign("hi");, an implementation would do the efficient thing for both. libstdc++, for instance, has its operator=(const CharT*) just directly call assign
    – Barry
    Sep 25 at 13:40










    up vote
    3
    down vote














    Is it guaranteed by the standard that std::string will not give back allocated memory spontaneously if reassigned from a string of a smaller size?




    Regardless of the actual answer (which is "No, no guarantee") - you should employ the following principle: If it's not obvious that it has to be the case, then don't assume it is the case.



    In your specific case - if you want tight control of heap behavior, you might not even want to use std::strings at all (maybe; it depends). And you might not want to use the default allocator (again, maybe); and you might want to memoize strings; etc. What you should absolutely do is make fewer assumptions, measure if possible, and have explicit design to ensure your needs are met.






    share|improve this answer


























      up vote
      3
      down vote














      Is it guaranteed by the standard that std::string will not give back allocated memory spontaneously if reassigned from a string of a smaller size?




      Regardless of the actual answer (which is "No, no guarantee") - you should employ the following principle: If it's not obvious that it has to be the case, then don't assume it is the case.



      In your specific case - if you want tight control of heap behavior, you might not even want to use std::strings at all (maybe; it depends). And you might not want to use the default allocator (again, maybe); and you might want to memoize strings; etc. What you should absolutely do is make fewer assumptions, measure if possible, and have explicit design to ensure your needs are met.






      share|improve this answer
























        up vote
        3
        down vote










        up vote
        3
        down vote










        Is it guaranteed by the standard that std::string will not give back allocated memory spontaneously if reassigned from a string of a smaller size?




        Regardless of the actual answer (which is "No, no guarantee") - you should employ the following principle: If it's not obvious that it has to be the case, then don't assume it is the case.



        In your specific case - if you want tight control of heap behavior, you might not even want to use std::strings at all (maybe; it depends). And you might not want to use the default allocator (again, maybe); and you might want to memoize strings; etc. What you should absolutely do is make fewer assumptions, measure if possible, and have explicit design to ensure your needs are met.






        share|improve this answer















        Is it guaranteed by the standard that std::string will not give back allocated memory spontaneously if reassigned from a string of a smaller size?




        Regardless of the actual answer (which is "No, no guarantee") - you should employ the following principle: If it's not obvious that it has to be the case, then don't assume it is the case.



        In your specific case - if you want tight control of heap behavior, you might not even want to use std::strings at all (maybe; it depends). And you might not want to use the default allocator (again, maybe); and you might want to memoize strings; etc. What you should absolutely do is make fewer assumptions, measure if possible, and have explicit design to ensure your needs are met.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Sep 26 at 11:35

























        answered Sep 25 at 21:29









        einpoklum

        30.7k24107219




        30.7k24107219




















            up vote
            2
            down vote













            If your strings are short (up to 15 or 22 bytes, depending on the compiler/std lib) and you are using a relatively recent compiler in C++11 or later mode, then you are likely to benefit from the Short String Optimization (SSO). In this case the string contents are not separately allocated on the heap.



            This link also contains a lot of details on common implementations and allocation strategies.



            However, both of the strings in your example are too long for SSO.






            share|improve this answer




















            • Is it guaranteed by the standard? Is SSO guaranteed by the standard?
              – pipe
              Sep 26 at 0:40










            • @pipe No it isn't, what Paul implied in: "you are likely to benefit from the Short String Optimization (SSO)".
              – YSC
              Sep 26 at 7:17










            • @YSC Ok, but the question is rather specific, and OP already knows that it is likely to happen since he depends on it, so I don't understand what this actually answers.
              – pipe
              Sep 26 at 8:27










            • @pipe I agree this answer is slightly off, but it was answered right after OP asked their question. The question wasn't tagged language-lawyer at that time, and get edited after that. This is answering part of OP concern (mem frag) and provides an interesting insight. I've upvoted it for what it's worth.
              – YSC
              Sep 26 at 9:44











            • It's not meant to be a full answer, just a complement for the case of SSO. I think that the link is quite interesting regarding practical measures of std::string performance.
              – Paul Floyd
              Sep 26 at 10:52














            up vote
            2
            down vote













            If your strings are short (up to 15 or 22 bytes, depending on the compiler/std lib) and you are using a relatively recent compiler in C++11 or later mode, then you are likely to benefit from the Short String Optimization (SSO). In this case the string contents are not separately allocated on the heap.



            This link also contains a lot of details on common implementations and allocation strategies.



            However, both of the strings in your example are too long for SSO.






            share|improve this answer




















            • Is it guaranteed by the standard? Is SSO guaranteed by the standard?
              – pipe
              Sep 26 at 0:40










            • @pipe No it isn't, what Paul implied in: "you are likely to benefit from the Short String Optimization (SSO)".
              – YSC
              Sep 26 at 7:17










            • @YSC Ok, but the question is rather specific, and OP already knows that it is likely to happen since he depends on it, so I don't understand what this actually answers.
              – pipe
              Sep 26 at 8:27










            • @pipe I agree this answer is slightly off, but it was answered right after OP asked their question. The question wasn't tagged language-lawyer at that time, and get edited after that. This is answering part of OP concern (mem frag) and provides an interesting insight. I've upvoted it for what it's worth.
              – YSC
              Sep 26 at 9:44











            • It's not meant to be a full answer, just a complement for the case of SSO. I think that the link is quite interesting regarding practical measures of std::string performance.
              – Paul Floyd
              Sep 26 at 10:52












            up vote
            2
            down vote










            up vote
            2
            down vote









            If your strings are short (up to 15 or 22 bytes, depending on the compiler/std lib) and you are using a relatively recent compiler in C++11 or later mode, then you are likely to benefit from the Short String Optimization (SSO). In this case the string contents are not separately allocated on the heap.



            This link also contains a lot of details on common implementations and allocation strategies.



            However, both of the strings in your example are too long for SSO.






            share|improve this answer












            If your strings are short (up to 15 or 22 bytes, depending on the compiler/std lib) and you are using a relatively recent compiler in C++11 or later mode, then you are likely to benefit from the Short String Optimization (SSO). In this case the string contents are not separately allocated on the heap.



            This link also contains a lot of details on common implementations and allocation strategies.



            However, both of the strings in your example are too long for SSO.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Sep 25 at 10:43









            Paul Floyd

            2,54611729




            2,54611729











            • Is it guaranteed by the standard? Is SSO guaranteed by the standard?
              – pipe
              Sep 26 at 0:40










            • @pipe No it isn't, what Paul implied in: "you are likely to benefit from the Short String Optimization (SSO)".
              – YSC
              Sep 26 at 7:17










            • @YSC Ok, but the question is rather specific, and OP already knows that it is likely to happen since he depends on it, so I don't understand what this actually answers.
              – pipe
              Sep 26 at 8:27










            • @pipe I agree this answer is slightly off, but it was answered right after OP asked their question. The question wasn't tagged language-lawyer at that time, and get edited after that. This is answering part of OP concern (mem frag) and provides an interesting insight. I've upvoted it for what it's worth.
              – YSC
              Sep 26 at 9:44











            • It's not meant to be a full answer, just a complement for the case of SSO. I think that the link is quite interesting regarding practical measures of std::string performance.
              – Paul Floyd
              Sep 26 at 10:52
















            • Is it guaranteed by the standard? Is SSO guaranteed by the standard?
              – pipe
              Sep 26 at 0:40










            • @pipe No it isn't, what Paul implied in: "you are likely to benefit from the Short String Optimization (SSO)".
              – YSC
              Sep 26 at 7:17










            • @YSC Ok, but the question is rather specific, and OP already knows that it is likely to happen since he depends on it, so I don't understand what this actually answers.
              – pipe
              Sep 26 at 8:27










            • @pipe I agree this answer is slightly off, but it was answered right after OP asked their question. The question wasn't tagged language-lawyer at that time, and get edited after that. This is answering part of OP concern (mem frag) and provides an interesting insight. I've upvoted it for what it's worth.
              – YSC
              Sep 26 at 9:44











            • It's not meant to be a full answer, just a complement for the case of SSO. I think that the link is quite interesting regarding practical measures of std::string performance.
              – Paul Floyd
              Sep 26 at 10:52















            Is it guaranteed by the standard? Is SSO guaranteed by the standard?
            – pipe
            Sep 26 at 0:40




            Is it guaranteed by the standard? Is SSO guaranteed by the standard?
            – pipe
            Sep 26 at 0:40












            @pipe No it isn't, what Paul implied in: "you are likely to benefit from the Short String Optimization (SSO)".
            – YSC
            Sep 26 at 7:17




            @pipe No it isn't, what Paul implied in: "you are likely to benefit from the Short String Optimization (SSO)".
            – YSC
            Sep 26 at 7:17












            @YSC Ok, but the question is rather specific, and OP already knows that it is likely to happen since he depends on it, so I don't understand what this actually answers.
            – pipe
            Sep 26 at 8:27




            @YSC Ok, but the question is rather specific, and OP already knows that it is likely to happen since he depends on it, so I don't understand what this actually answers.
            – pipe
            Sep 26 at 8:27












            @pipe I agree this answer is slightly off, but it was answered right after OP asked their question. The question wasn't tagged language-lawyer at that time, and get edited after that. This is answering part of OP concern (mem frag) and provides an interesting insight. I've upvoted it for what it's worth.
            – YSC
            Sep 26 at 9:44





            @pipe I agree this answer is slightly off, but it was answered right after OP asked their question. The question wasn't tagged language-lawyer at that time, and get edited after that. This is answering part of OP concern (mem frag) and provides an interesting insight. I've upvoted it for what it's worth.
            – YSC
            Sep 26 at 9:44













            It's not meant to be a full answer, just a complement for the case of SSO. I think that the link is quite interesting regarding practical measures of std::string performance.
            – Paul Floyd
            Sep 26 at 10:52




            It's not meant to be a full answer, just a complement for the case of SSO. I think that the link is quite interesting regarding practical measures of std::string performance.
            – Paul Floyd
            Sep 26 at 10:52

















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52495704%2fis-stdstring-guaranteed-not-to-give-back-memory-spontaneously%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?