Facebook Interview Question
Software Engineer / Developerscopy on write means, there is an actual copy made , only when there the string is actually altered.
For eg,
String a="hello";
String b=a; <- both b and a object share same mem location of "hello"
but b[0] ='H' ; -> a write , so b's content is copied and then modified, so
a=hello and b=Hello .
You basically have to implement this class, so that u keep track of these things in copy constructor/assignment operator or any method which modifies the string.
how about this implementation?
#include <cstdio>
#include <cstring>
#include <cstdlib>
class String {
public:
String();
String(const char * s);
~String();
String(const String& s);
String& operator=(const String& s);
void swap(String& s);
const char * c_str();
private:
size_t allocbuf(char ** buf, size_t size);
void freebuf(char * buf);
char * buf;
size_t max_size;
size_t size;
mutable bool local;
};
String::String()
: buf(0),
max_size(0),
size(0),
local(false)
{}
String::String(const char *s)
{
if (! s or ! *s) return;
size_t slen = strlen(s) + 1;
char * buffer;
size_t mlen = allocbuf(&buffer, slen);
if (! mlen) return;
memcpy(buffer, s, slen);
// resource alloc succeed. exception free construction
buf = buffer;
max_size = mlen;
size = slen - 1; // no needs to count in ASCIIZ.
local = true;
}
String::~String()
{
printf("%p: I'm in destructor.\n", this);
if (local) {
// local, free up the resource
freebuf(buf);
printf(" %p: free(%p).\n", buf);
}
}
String::String(const String& other)
{
local = false;
buf = other.buf;
max_size = other.max_size;
size = other.size;
}
String&
String::operator=(const String& other)
{
String tmp(other);
swap(tmp);
return *this;
}
void
String::swap(String& other)
{
String tmp(other);
other.local = local;
other.buf = buf;
other.max_size = max_size;
other.size = size;
local = tmp.local;
buf = tmp.buf;
max_size = tmp.max_size;
size = tmp.size;
}
inline const char *
String::c_str()
{
return buf;
}
// power of 2 memory allocator
size_t
String::allocbuf(char ** s, size_t size)
{
size_t bytes;
if (! (size & (size - 1)))
{
bytes = size;
}
else {
size_t boffset = sizeof(size_t) * 8 - 1;
for (; ! ((1UL << boffset) & size); -- boffset);
bytes = 1UL << (boffset + 1);
}
* s = (char *) malloc(bytes);
if (!* s) return 0;
return bytes;
}
void
String::freebuf(char * s)
{
return free(s);
}
// notes:
// 1. try to write exception safe codes. swap() might be overkill here.
// 2. throw in a power-of-2 allocator for the class.
// 3. no STL mess.
// 4. no append(), erase(), destroy(), operator+() yet.
//
// tested with the following simple codes, memory allocation make sense.
int
main()
{
String s1("career cup is a killer app");
String s2("facebook is a killer site");
String s = s1;
s = s2;
printf("s = %s\n", s.c_str());
}
Could you give some more details?
- sdm February 28, 2010