0
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <string>

using namespace std;

int main()
{
    ostringstream out;
    ostringstream tmpstr;
    tmpstr << "ritesh is here";
    out << tmpstr.str().c_str();
    out << endl;
    cout << out.str();
    if(tmpstr.rdbuf()!=NULL)
        cout << "tmpstr not null" <<endl;
    else
        cout << "tmpstr null" <<endl;
    delete tmpstr.rdbuf();   // This line gives me segmentation fault
    cout <<"deleted" << endl;
}

The line delete tmpstr.rdbuf(); gives a segmentation fault . I guess rdbuf returns char* pointer and hence . I can use a delete on it to free the memory space allocated to tmpstr

Am i wrong Somewhere ?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Invictus
  • 4,028
  • 10
  • 50
  • 80
  • 2
    [Resource Acquisition is Initialization](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization). Know it. Love it. – Ed S. May 11 '12 at 18:40
  • @EdS.: While good advice, I don't see how it applies here. – John Dibling May 11 '12 at 18:41
  • 2
    @JohnDibling: Because this is how `std::string` works. If you understand that then you will understand that you don't need to call `delete` on anything here. Given, it's a higher level concept than what the OP is asking for, but if you're going to be using `string`'s, `vector`'s, etc. you should understand what is going on behind the scenes. – Ed S. May 11 '12 at 18:42
  • 1
    Ritesh does not need to know anything about RAII or the inner workings of `string` or `vector` in order to understand that `delete`ing `tmpstr.rdbuf();` is bad. – John Dibling May 11 '12 at 19:09

1 Answers1

7

Yes you're wrong in thinking that you can delete something that you did not allocate.

Only delete things you have newed yourself. Don't delete someone else's stuff.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • Nitpick: Only `delete` things that have been allocated with `new`. Sometimes a function you didn't write allocates memory that you are responsible for cleaning up. Just because you didn't call `new` doesn't mean you don't ever call `delete`. – Ed S. May 11 '12 at 18:41
  • 4
    *"Don't delete someone else's stuff."* unless they told you to do so *explicitly* in the doccumentation. – Alok Save May 11 '12 at 18:44
  • @Als: Yeah that's what I was getting at :D – Ed S. May 11 '12 at 18:46
  • 1
    @Als: and if the doucmentation says it's required, look for alternatives that aren't so poorly designed. This should *almost* never be needed (passing objects between threads being a reasonable exception). – Jerry Coffin May 11 '12 at 18:56
  • @JerryCoffin: Good luck with that. You don't always have the luxury of a perfectly design API. Also, many API's are meant to be C compatible, which means knowing what to do with a function's return values. – Ed S. May 11 '12 at 19:01
  • @EdS.: There's a lot of room between "perfect" and "clueless" though. – Jerry Coffin May 11 '12 at 19:05
  • @JerryCoffin: Sure, but in my experience (systems programming) you often have little choice, and API's written by people who may be primarily hardware guys... well, you get the idea. Of course, because if this, I am probably a bit biased. – Ed S. May 11 '12 at 19:07
  • @EdS.: But that's hardly general advice in the general case. – Puppy May 11 '12 at 19:12
  • @Ed S: If other code called new and returned a pointer they wanted you to delete then they should not be returning a pointer but a std::auto_ptr<> (or other sp) to indicate the transfer of ownership. Also in which case you should **not** call delete but let the smart pointer do its work. So I reject your hypothesis as wrong. A pointer returned from code that is not yours should not be deleted (any documentation to show that you should indicates badly written code and you should change the library you are using and temporarily provide a wrapper fro that function that does the wrapping for you). – Martin York May 11 '12 at 19:33
  • 2
    @LokiAstari: I guess you're right in a theoretical world where all the API's in existence were so well designed. Of course they are not, so I reject your hypothesis as wrong. You seem to live in a fantasy world; I live in the real world, where you are often stuck using an API that returns a pointer that you are responsible for deallocating. What do you do in your day job that allows you such freedom to always find an API that you deem "well written"? The wrapper I agree with (and do), but of course, at some point you are still deallocating that memory, you just moved the code around a bit. – Ed S. May 11 '12 at 20:28
  • 1
    @LokiAstari: Let me put it another way; I deal with device drivers. A lot. You have no freedom to dismiss the API as unsuitable. You use it because you are forced to. This is often the reality. – Ed S. May 11 '12 at 20:30
  • I very much doubt that all this elaboration on corner cases and unusual exceptions is really helping the OP to understand why `delete`ing `tmpstr.rdbuf()` is bad. – John Dibling May 11 '12 at 20:37
  • @JohnDibling: I second that & that is the reason I stooped this conversion after the first comment which raised an objection citing *best practices*.Too much detail in too little time just creates confusion.What the OP needs to know here is S/He should not call `delete` on an address not returned by `new`,the rest of the ownership & good api design pedantry might fit in well in a book not in comments though it is important it doesn't seem to be the need of the hour for the OP.Learning is an step by step process and too much detail would leave one lost. – Alok Save May 12 '12 at 12:22