真奇怪的分段错误

时间:2017-11-18 18:50:53

标签: c++ segmentation-fault

在下面的代码中,我使用文件名调用editorOpen方法。 它总是会产生分段错误,除非我在editorUpdateRowstd::string rowStr(row);)中注释掉第一行。 有人能解释为什么会这样吗?

void editorUpdateRow(const std::string& row)
{
    std::string rowStr(row);
    size_t index = 0;
    while (index != std::string::npos)
    {
        index = rowStr.find("\t", index);
        if (index != std::string::npos)
        {    
            rowStr.replace(index, 1, KILO_TAB);
            index += sizeof(KILO_TAB) - 1;
        }
    }
}

void editorAppendRow(char* row, size_t len)
{
    config.rows = static_cast<std::string*>(realloc(config.rows, sizeof(std::string) * (config.numRows + 1)));
    KILO_SANITY(config.rows != nullptr, "Couldn't realloc rows array");
    printf("%d\n", config.numRows);
    config.rows[config.numRows] = row;
    printf("%d\n", __LINE__);
    config.rows[config.numRows][len] = '\0';
    printf("%d\n", __LINE__);
    editorUpdateRow(config.rows[config.numRows]);

    ++config.numRows;
}

void editorOpen(char* filename)
{
    KILO_SANITY(filename != nullptr, "Filename is NULL!!!");
    FILE* fp = fopen(filename, "r");
    KILO_SANITY(fp, "Open of %s Failed!!!", filename);
    char* line = nullptr;
    size_t linecap = 0;
    ssize_t linelen = 0;
    while((linelen = getline(&line, &linecap, fp)) != -1)
    {
            while (linelen > 0 && (line[linelen - 1] == '\n' ||
                   line[linelen - 1] == '\r'))
            {
                --linelen;
            }
            editorAppendRow(line, linelen);
    }

    free(line);
    fclose(fp);
}

1 个答案:

答案 0 :(得分:1)

std::string是一个非平凡的类,需要适当的构造才能运行。 malloc只是分配内存。它不运行构造函数,因此分配的string的状态是未初始化的。 string的内部字符缓冲区Crom知道其中的位置,未定义的长度,以及字符串实现中使用的其他任何簿记都未设置为有意义的值。 malloc编辑string是一个等待离开的炸弹。

因为malloc与复杂数据类型一起使用是危险的(并且因为它可能导致大小错误),所以它几乎不应该在C ++中使用。

当被迫分配动态存储时,首选(按顺序)

  1. a library container
  2. std::make_unique
  3. std::make_shared
  4. new
  5. 选择符合对象要求的列表中最早的那个。

    本身,string几乎是一个库容器,一个字符容器,因此动态分配string几乎不是正确的选择。如果您希望避免复制,可以通过引用传递它并转移所有权with std::move