C ++ struct初始化

时间:2017-01-04 15:44:19

标签: c++

我在somecode.h中有以下结构声明:

    struct MySt
    {
        MySt( const char * m, const char * gm ):
            firstSen(m),
            secondSen(gm)
        {
        }

        std::string firstSen;
        std::string secondSen;
    };

以下是somecode.cpp中的代码:

        std::vector<MySt> dataSen;

        char * cp = trim(buff);
        std::vector<std::string> tokens;

        getTokens( cp, tokens );

        if(tokens.size() == 2 )
        {

            dataSen.push_back( MySt(tokens[0].c_str(), tokens[1].c_str() ));
        }

此代码有效。我的问题是:这种类型的MySt初始化,是堆栈还是堆,它是动态还是静态分配的? 日Thnx。

2 个答案:

答案 0 :(得分:2)

这里有很多事情发生。

dataSen是一个向量,这意味着它在堆栈上有少量空间来存储指向其存储的指针以及一些开销的东西(如大小等),但它存储的所有东西都在通过它管理的分配堆。

std::string,dataSen存​​储的类型,实际上有少量数据存储在向量中(同样存储在堆中),然后创建它自己的堆分配它的数据。 (可以进行小的字符串优化,但超出了此范围)。

所以你把东西读成一个标记向量,它将数据存储为字符串。字符串的存储位于堆上(通过向量的堆分配),实际字符的字符串中存储(通过字符串管理的堆分配)。

然后使用c_str()从每个字符串中获取const char*引用以创建临时MySt(它创建了两个新字符串,由const char *&#39; s初始化)。然后将此临时文件复制到向量中,这意味着它存储在由向量管理的堆上,每个字符串数据通过字符串管理的不同分配存储在堆上。

现在......这些都不是真的,因为优化器可以做很多技巧,但这就是你要求完成的事情。

巧合的是,如果您使用emplace_back(const char*, const char*)代替push_back(MySt(...)),那么您可以将其构建到位而不是临时移动。

此外,如果你为MySt添加了一个带有std :: string&amp;&amp;的构造函数。您可以将已创建的字符串移动到MySt中,以避免转换为const char *,然后再创建另一个字符串。

编辑您的评论:

struct MySt
{
    // existing constructor, creating strings from const char*
    MySt( const char * m, const char * gm ):
        firstSen(m),
        secondSen(gm)
    {
    }

    // constructor copying string inputs
    MySt( const std::string& m, const std::string& gm) :
        firstSen(m),
        secondSen(gm)
    {
    }

    // constructor moving existing strings (strings from calling code
    // will be in an unusable state other than to re-assign them to
    // something new... but it will take the allocated heap from the
    // existing strings as to avoid making another heap allocation)
    MySt( std::string&& m, std::string&& gm) :
        firstSen(std::move(m)),
        secondSen(std::move(gm))
    {
    }

    std::string firstSen;
    std::string secondSen;
};

然后使用......

getTokens( cp, tokens );

if(tokens.size() == 2 )
{
    // to copy...
    dataSen.emplace_back( tokens[0], tokens[1] );

    // or to move...
    dataSen.emplace_back( std::move(tokens[0]), std::move(tokens[1]) );
}

答案 1 :(得分:0)

  • 如果您将对象声明为全局或静态本地,则它们是 静态分配。
  • 如果您在一个块中声明,它们将被分配到堆栈中。
  • 如果使用new关键字,则会在堆上分配它们。
  • STL容器的元素也存储在堆上。