初始化失败

时间:2014-12-21 11:38:28

标签: c++ visual-studio-2010

我试图赶上C ++并遇到一些我无法找到解决方案的问题。我正在使用一个类是std :: string的简单版本,这个类仅用于测试/学习目的'。谁可以帮我提出一些关于我做错事的建议。

问题简短:

我创建了一个带有复制构造函数和析构函数的类Str。 直接初始化没有问题。

Str a = "Hello";  // OK.

作业失败;

Str a;
a = "Hello";  // Failing.

下面提供了代码的反汇编以及出错的标识(根据我)。

注意:a = Str的版本(" Hello");显示同样的效果。

我知道出了什么问题,但我不知道如何纠正它。 在第一种情况下

Str a = "Hello"; 
// The constructor Str::Str(const char* value) is used. No problem.

在第二种情况下

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.

我在这里做错了什么?我是否在关于如何分配值的C ++语义上遗漏了一些内容?

这是我使用的实际代码。

#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

及其实施:

#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头文件

// 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"

和实际的节目。

#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;
}

程序部分的反汇编。

--- 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

0 个答案:

没有答案