将字符串存储为char []并将其放置为new并将其恢复

时间:2015-09-25 07:47:36

标签: c++ string pointer-arithmetic placement-new

我想编写一个Class,它保存有关Memory中字符串的信息,并且可以将它返回给我。所以我开始使用一个拥有字符串大小的联盟。 (为什么union在这里并不重要,但它需要在其他类型的联合后面)构造函数得到一个传递的字符串,并应该把字符串作为c_str放在Objekt的末尾,我放置new。 该课程如下:

class PrimitivTyp
{
public:
    explicit PrimitivTyp(const std::string &s);
    std::shared_ptr<std::string> getString() const;
private:
    union
    {
        long long m_long; //use long long for string size
        double m_double;
    } m_data;
    ptrdiff_t m_next;
};

Ctor和get函数的impl看起来像这样,我猜不正常。

PrimitivTyp::PrimitivTyp(const std::string& s)
{
    m_data.m_long = s.size();
    m_next = reinterpret_cast<ptrdiff_t>(nullptr);
    //calc the start ptr
    auto start = reinterpret_cast<ptrdiff_t*>(this + sizeof(PrimitivTyp));
    memcpy(start, s.c_str(), s.size()); //cpy the string
}

std::shared_ptr<std::string> PrimitivTyp::getString() const
{
    auto string = std::make_shared<std::string>();
    //get the char array
    auto start = reinterpret_cast<ptrdiff_t>(this + sizeof(PrimitivTyp)); //get the start point
    auto size = m_data.m_long; //get the size
    string->append(start, size);//appand it
    return string;//return the shared_ptr as copy
}

用法应该是这样的:

int main(int argc, char* argv[])
{
    //checking type
    char buffer[100];
    PrimitivTyp* typ = new(&buffer[0]) PrimitivTyp("Testing a Type");
    LOG_INFO << *typ->getString();
}

这会崩溃,我找不到调试器的错误。我认为这是this的位置计算。

1 个答案:

答案 0 :(得分:1)

this + sizeof(PrimitivTyp)不是您的想法,您想要this + 1reinterpret_cast<uint8_t*>(this) + sizeof(PrimitivTyp)

C和C ++中的指针算法考虑了指针的类型。

因此,对于T* t;(t + 1)&t[1](假设operator &非重载)或reinterpret_cast<T*>(reinterpret_cast<uint8_t>(t) + sizeof(T))