1

Assume I want to write my own string class. The string has a property char * s which is a pointer that points to a character.

Now in the constructor, String::String(), what would you pass in to assume another char * to that? You can't really do something like the code below since both pointers will point to the same thing (and we don't want that):

String::String(const char *str) {
        s = str;
}

Any help is appreciated!

darksky
  • 20,411
  • 61
  • 165
  • 254
  • You want something like this:http://stackoverflow.com/questions/4691608/copying-non-null-terminated-unsigned-char-array-to-stdstring – N_A Sep 14 '11 at 17:15

3 Answers3

3

You need to deep copy the string, i.e. create a character buffer long enough to incorporate the contents of str, then copy the contents into it. The simplest way to achieve that would be using strdup strcpy, since the former is nonstandard:

s = new char[strlen (str) + 1];
if (s == NULL) throw some_exception;
strcpy (s, str);
Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • The memory for a string returned from `strdup` is obtained with `malloc`. Isn't it potentially dangerous do call delete[] on that memory considering that `delete` could be overloaded? Maybe you should advice to free the memory with `free`. – pmr Sep 14 '11 at 17:17
  • 1
    That `new` does never return `NULL`. The second line should be omitted. – Sebastian Mach Dec 13 '11 at 11:51
  • @phresnel, see e.g. http://stackoverflow.com/questions/550451/will-new-return-null-in-any-case – Péter Török Dec 13 '11 at 12:33
  • @PeterTörök: So? You are not using the nothrow variant, which is why I wrote _that_. – Sebastian Mach Dec 13 '11 at 13:09
2

Please do not write your own string class. There are hell of a lot of details you have to know not to introduce mistakes (for example, overloaded operators, boolean idioms etc), and a lot more details to make that string class efficient (for example, implement copy-on-write) etc. But just for educational purposes, you have to make a copy of the passed string. Here is an example:

#include <cstdint>
#include <cstring>
#include <cstdio>

class String
{
    char *p_;

public:
    explicit String (const char *str)
    {
        auto length = std::strlen (str) + 1;
        p_ = new char [length];
        std::memcpy (p_, str, length);
    }

    ~String ()
    {
        delete [] p_;
        p_ = nullptr;
    }

    inline const char *c_str () const
    {
        return p_;
    }
};

int
main ()
{
    String s ("Hello, world!");
    std::printf ("%s\n", s.c_str ());
}
1

You should copy contents of null-terminated string that is passed as parameter.

One thing is that you might remove terminating null, because if you have your own class you can manage string boundaries manually by keeping current length.

Andrey
  • 59,039
  • 12
  • 119
  • 163