Home > OS >  PPP Stroustrup exercise - copy a C-style string into memory it allocates on the free store [duplicat
PPP Stroustrup exercise - copy a C-style string into memory it allocates on the free store [duplicat

Time:09-22

I'm solving the following exercise (17.4) from Stroustrup's PPP book:

Write a function char* strdup(const char* ) that copies a C-style string into memory it allocates on the free store. Don't use any standard library function.

Here's my implementation, which compiles just fine. I have a question about an error message that I found when I run the function.

#include <iostream>
#include <string>
char* strdup(const char* s) {
    if (s==0) return 0;

    // get number of char in s
    int n = 0;
    while (s[n] != 0)
          n;

    // allocate memory with room for terminating 0
    char* pc = new char[n 1];

    // copy string
    for (int i = 0; s[i];   i)
        pc[i] = s[i];
    pc[n] = 0;  // zero at the end: it's a C-style string

    delete[] s;
    return pc;
}

int main()
try {
    std::string str;
    char* cstr;
    while (std::cin>>str && str!="quit") {
        cstr = strdup(&str[0]);
        std::cout << cstr << "\n";
        delete[] cstr;
    }
}
catch (std::exception& e) {
    std::cerr << "exception: " << e.what() << std::endl;
}
catch (...) {
    std::cerr << "exception\n";
}

It compiles, but when I run it and I write the first character, I have a pointer being freed was not allocatederror. If I remove delete[] s, then I have no memory leak and it runs just fine. But why is (apparently) correct to do not delete[]the s? Is it because it has not been allocated with new?

CodePudding user response:

A std::string does manage the memory it uses to store the string. In main you do

 std::string str;

and

cstr = strdup(&str[0]);

but your strdup calls delete[] s; on the parameter.

This is what you already know. Now consider that the destructor of std::string does already clean up the memory when it goes out of scope. The buffer used by the std::string cannot be deleted twice. You shall not call delete on &str[0]. You only need to delete objects that you created via new.

Also there is small string optimization. In this case &str[0] does not point to a heap allocated buffer which you could delete.


PS: You are using 0 when you should rather use nullptr for pointers and '\0' for the null terminator.

  • Related