C++ 使用std::initializer\u list时出现分段错误<;标准::字符串>;在构造函数中

C++ 使用std::initializer\u list时出现分段错误<;标准::字符串>;在构造函数中,c++,c++11,segmentation-fault,c++14,C++,C++11,Segmentation Fault,C++14,嗨,我试图了解构造函数是如何工作的,所以我阅读了不同的例子。我有一个类构造函数,它接受一个初始值设定项列表,但它不断给出分段错误。我的档案如下: strvec.h 我的问题是如何解决这个问题,为什么我会遇到这个分段错误,这意味着什么,以便我将来可以避免它 PS:我知道错误是由于StrVec(std::initializer\u list il)引起的构造函数,因为如果我删除它以及它在mainfile.cpp中的使用,分段错误就会消失。[在这里猜测,因为你没有显示正确的错误。] 你的课堂上有一组指

嗨,我试图了解构造函数是如何工作的,所以我阅读了不同的例子。我有一个类构造函数,它接受一个初始值设定项列表,但它不断给出
分段错误
。我的档案如下:

  • strvec.h
  • 我的问题是如何解决这个问题,为什么我会遇到这个
    分段错误
    ,这意味着什么,以便我将来可以避免它


    PS:我知道错误是由于
    StrVec(std::initializer\u list il)引起的构造函数,因为如果我删除它以及它在mainfile.cpp中的使用,
    分段错误
    就会消失。

    [在这里猜测,因为你没有显示正确的错误。]

    你的课堂上有一组指针

    您的
    StrVec(std::initializer\u list il)
    构造函数不初始化这些指针,因此
    push\u back
    很可能会使用这些未初始化的指针,您将有未定义的行为和崩溃

    通过将默认初始化委托给默认构造函数,可以轻松地进行默认初始化:

    StrVec::StrVec(std::initializer_list<std::string> il)
        : StrVec()  // Delegte default initialization
    {
        for(const auto &s:il){
            push_back(s);
        }
    }
    
    StrVec::StrVec(std::initializer\u list il)
    :StrVec()//删除默认初始化
    {
    用于(const auto&s:il){
    推回;
    }
    }
    


    也就是说,
    std::initializer_list
    将有一个大小,这意味着您可以预先分配所需元素的确切数量,然后复制它们,而不是在循环中调用
    push_back

    请包括一个示例以及从调试器和地址消除器等工具中学到的内容。我知道错误是由于
    StrVec(std::initializer\u list il)构造函数,因为如果我删除它以及它在main file.cpp中的使用,那么分段错误就会消失,但我们甚至不知道该构造函数除了调用
    push_back
    之外还能做什么,我们自己也无法尝试
    只调用一个函数
    push_back
    ,而您没有提供itI的实现。我添加了push_back()成员。是的,这似乎修复了
    分段错误
    。因此,据我所知,现在这样说是否正确:“因为我们在类中有三个指针,并且我们没有为它们提供任何初始化,所以它们在初始化之前是默认的,这意味着它们有未定义的行为。为了解决这个问题,我们要么将工作委托给默认构造函数,要么在
    StrVec::StrVec(std::initializer\u list il)
    body-like-elements=first\u-free=cap=nullptr;“或者我们也可以对它们进行成员初始化。我上面的语句正确吗?@JasonLiam类似于这样的话是的。好吧,我尝试了
    StrVec::StrVec(std::initializer_list il):元素(nullptr),first_free(nullptr),cap(nullptr){for(const auto&s:il){push_back(s);}
    ,这很有效。谢谢
    StrVec::StrVec(const StrVec &s){
        auto newdata = alloc_n_copy(s.begin(), s.end());
        elements     = newdata.first;
        first_free   = cap = newdata.second;
    }
    
    StrVec::StrVec(std::initializer_list<std::string> il){
        for(const auto &s:il){
            push_back(s);
        }
    }
    std::pair<std::string*, std::string*> StrVec::alloc_n_copy(const std::string *b, const std::string *e){
        auto data = alloc.allocate(e - b);
        return {data, uninitialized_copy(b, e, data)};
    }
    void StrVec::push_back(const std::string& s){
        chk_n_alloc();
        alloc.construct(first_free++, s);
    }
    
    int main() {
    StrVec sv10 { "il1", "il2", "il3", "il4", "il5" };
    return 0;
    }
    
    StrVec::StrVec(std::initializer_list<std::string> il)
        : StrVec()  // Delegte default initialization
    {
        for(const auto &s:il){
            push_back(s);
        }
    }