在下面的代码中,我使用文件名调用editorOpen
方法。
它总是会产生分段错误,除非我在editorUpdateRow
(std::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);
}
答案 0 :(得分:1)
std::string
是一个非平凡的类,需要适当的构造才能运行。 malloc
只是分配内存。它不运行构造函数,因此分配的string
的状态是未初始化的。 string
的内部字符缓冲区Crom知道其中的位置,未定义的长度,以及字符串实现中使用的其他任何簿记都未设置为有意义的值。 malloc
编辑string
是一个等待离开的炸弹。
因为malloc
与复杂数据类型一起使用是危险的(并且因为它可能导致大小错误),所以它几乎不应该在C ++中使用。
当被迫分配动态存储时,首选(按顺序)
std::make_unique
std::make_shared
new
选择符合对象要求的列表中最早的那个。
本身,string
几乎是一个库容器,一个字符容器,因此动态分配string
几乎不是正确的选择。如果您希望避免复制,可以通过引用传递它并转移所有权with std::move
。