I try to catch up with C++ and ran in some problems for which I cannot find a solution. I'm working with a class which is a simple version of std::string, this class is for 'testing/learning purposes only'. Who can help me with some advise on what I'm doing wrong.
The problem in short:
I created a class Str with a copy constructor and a destructor. Direct initialisation gives no problem.
Str a = "Hello";  // OK.
Assignment is failing;
Str a;
a = "Hello";  // Failing.
A disassembly of the code and an identification on what goes wrong (according to me) is available below.
Note: the version with a = Str("Hello"); shows the same effect.
I know what goes wrong but I do not know how to correct it. In the first case
Str a = "Hello"; 
// The constructor Str::Str(const char* value) is used. No problem.
In the second case
Str a;
// The default constructor Str::Str() is used. No problem.
a = "Hello";
// 001D1557: The constructor Str::Str(const char* value) is used creating instance a'. No problem.
// 001D155C: Instance a' is copied over a. No problem yet.
// 001D157D: The desctuctor for a' is called, which in the process destoys the char* used by a, corrupting it.
What am I doing wrong here? Am I missing some point on the C++ semantics on how to assign a value?
Here is the actual code that I use.
#pragma once
namespace Steenveld {
namespace Base {
class Str {
public:
    Str();
    Str(const Str& value);
    Str(const Str* value);
    Str(const char* value);
    ~Str();
    inline const size_t& Length() const { return length; };
    inline const char* Value() const { return buffer; };
private:
    char* buffer;
    size_t length;
    size_t size;
    void Init(void);
    void SetBuffer(size_t size);
};
} // namespace Base
} // namespace Steenveld
And its implementation:
#include "stdafx.h"
namespace Steenveld {
namespace Base {
Str::Str() {
    Init();
}
Str::Str(const Str& value) {
    Init();
    length = value.length;
    SetBuffer(length+1);
    strcpy_s(buffer, size, value.buffer);
}
Str::Str(const Str* value) {
    Init();
    length = value->length;
    SetBuffer(length+1);
    strcpy_s(buffer, size, value->buffer);
}
Str::Str(const char* value) {
    Init();
    if (value != nullptr) {
        length = strlen(value);
        SetBuffer(length+1);
        strcpy_s(buffer, size, value);
    }
}
Str::~Str() {
    if (buffer != nullptr) {
        free(buffer);
        buffer = nullptr;
        size = 0;
        length = 0;
    }
}
void Str::Init(void) {
    buffer = nullptr;
    length = 0;
    size = 0;
}
void Str::SetBuffer(size_t size) {
    if (size <= 0) return;
    if (buffer == nullptr) {
        buffer = (char*)malloc(size);
        this->size = size;
    } else if (this->size < size) {
        buffer = (char*)realloc(buffer, size);
        this->size = size;
    }
    buffer[size-1] = '\0';
}
} // namespace Base
} // namespace Steenveld
VS2010 header file
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
#pragma once
#include "targetver.h"
#include <iostream>
#include <tchar.h>
#include "Str.h"
And the actual program.
#include "stdafx.h"
using namespace Steenveld::Base;
int _tmain(int argc, _TCHAR* argv[])
{
    Str a;
    a = "Hell";
    std::cout << a.Value() << "\r\n";
    char n;
    std::cin.get(n);
    return 0;
}
The disassembly of the program part.
--- e:\andre\ontwikkeling\libconsole\consolenative\program.cpp -----------------
// ConsoleNative.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
using namespace Steenveld::Base;
int _tmain(int argc, _TCHAR* argv[])
{
001D1500  push        ebp  
001D1501  mov         ebp,esp  
001D1503  push        0FFFFFFFFh  
001D1505  push        offset __ehhandler$_wmain (1D5718h)  
001D150A  mov         eax,dword ptr fs:[00000000h]  
001D1510  push        eax  
001D1511  sub         esp,100h  
001D1517  push        ebx  
001D1518  push        esi  
001D1519  push        edi  
001D151A  lea         edi,[ebp-10Ch]  
001D1520  mov         ecx,40h  
001D1525  mov         eax,0CCCCCCCCh  
001D152A  rep stos    dword ptr es:[edi]  
001D152C  mov         eax,dword ptr [___security_cookie (1D9000h)]  
001D1531  xor         eax,ebp  
001D1533  push        eax  
001D1534  lea         eax,[ebp-0Ch]  
001D1537  mov         dword ptr fs:[00000000h],eax  
    Str a;
001D153D  lea         ecx,[ebp-1Ch]  
001D1540  call        Steenveld::Base::Str::Str (1D100Ah)  
001D1545  mov         dword ptr [ebp-4],0  
    a = "Hell";
001D154C  push        offset string "Hell" (1D7740h)  
001D1551  lea         ecx,[ebp-108h]  
001D1557  call        Steenveld::Base::Str::Str (1D1037h)  
001D155C  mov         eax,dword ptr [ebp-108h]  
001D1562  mov         dword ptr [ebp-1Ch],eax  
001D1565  mov         ecx,dword ptr [ebp-104h]  
001D156B  mov         dword ptr [ebp-18h],ecx  
001D156E  mov         edx,dword ptr [ebp-100h]  
001D1574  mov         dword ptr [ebp-14h],edx  
001D1577  lea         ecx,[ebp-108h]  
001D157D  call        Steenveld::Base::Str::~Str (1D1113h)  
    std::cout << a.Value() << "\r\n";
001D1582  push        offset string "\r\n" (1D773Ch)  
001D1587  lea         ecx,[ebp-1Ch]  
001D158A  call        Steenveld::Base::Str::Value (1D1104h)  
001D158F  push        eax  
001D1590  mov         eax,dword ptr [__imp_std::cout (1DA33Ch)]  
001D1595  push        eax  
001D1596  call        std::operator<<<std::char_traits<char> > (1D116Dh)  
001D159B  add         esp,8  
001D159E  push        eax  
001D159F  call        std::operator<<<std::char_traits<char> > (1D116Dh)  
001D15A4  add         esp,8  
    char n;
    std::cin.get(n);
001D15A7  mov         esi,esp  
001D15A9  lea         eax,[ebp-25h]  
001D15AC  push        eax  
001D15AD  mov         ecx,dword ptr [__imp_std::cin (1DA340h)]  
001D15B3  call        dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::get (1DA330h)]  
001D15B9  cmp         esi,esp  
001D15BB  call        @ILT+430(__RTC_CheckEsp) (1D11B3h)  
    return 0;
001D15C0  mov         dword ptr [ebp-0F4h],0  
001D15CA  mov         dword ptr [ebp-4],0FFFFFFFFh  
001D15D1  lea         ecx,[ebp-1Ch]  
001D15D4  call        Steenveld::Base::Str::~Str (1D1113h)  
001D15D9  mov         eax,dword ptr [ebp-0F4h]  
}
001D15DF  push        edx  
001D15E0  mov         ecx,ebp  
001D15E2  push        eax  
001D15E3  lea         edx,[ (1D1610h)]  
001D15E9  call        @ILT+160(@_RTC_CheckStackVars@8) (1D10A5h)  
001D15EE  pop         eax  
001D15EF  pop         edx  
001D15F0  mov         ecx,dword ptr [ebp-0Ch]  
001D15F3  mov         dword ptr fs:[0],ecx  
001D15FA  pop         ecx  
001D15FB  pop         edi  
001D15FC  pop         esi  
001D15FD  pop         ebx  
001D15FE  add         esp,10Ch  
001D1604  cmp         ebp,esp  
001D1606  call        @ILT+430(__RTC_CheckEsp) (1D11B3h)  
001D160B  mov         esp,ebp  
001D160D  pop         ebp  
001D160E  ret  
001D160F  nop  
001D1610  db          02h  
001D1611  db          00h  
001D1612  db          00h  
001D1613  db          00h  
001D1614  db          18h  
001D1615  db          16h  
001D1616  db          1dh  
001D1617  db          00h  
001D1618  db          e4h  
001D1619  db          ffh  
001D161A  db          ffh  
001D161B  db          ffh  
001D161C  db          0ch  
001D161D  db          00h  
001D161E  db          00h  
001D161F  db          00h  
001D1620  db          32h  
001D1621  db          16h  
001D1622  db          1dh  
001D1623  db          00h  
001D1624  db          dbh  
001D1625  db          ffh  
001D1626  db          ffh  
001D1627  db          ffh  
001D1628  db          01h  
001D1629  db          00h  
001D162A  db          00h  
001D162B  db          00h  
001D162C  db          30h  
001D162D  db          16h  
001D162E  db          1dh  
001D162F  db          00h  
001D1630  db          6eh  
001D1631  db          00h  
001D1632  db          61h  
001D1633  db          00h
