在下面的代码中,我使用文件名调用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("%dn", config.numRows);
config.rows[config.numRows] = row;
printf("%dn", __LINE__);
config.rows[config.numRows][len] = ' ';
printf("%dn", __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);
}
std::string
是一个非平凡的类,需要正确的构造才能发挥作用。malloc
只是简单地分配内存。它不运行构造函数,因此分配的string
的状态未初始化。string
的内部字符缓冲点Crom知道在哪里,它的长度是未定义的,并且在字符串的实现中使用的任何其他记账都没有设置为有意义的值。malloc
edstring
是一枚等待爆炸的炸弹
因为malloc
与复杂的数据类型一起使用是危险的(而且可能会导致大小错误),所以它几乎不应该在C++中使用。
当被迫分配动态存储时,首选(按顺序)
- 库容器
std::make_unique
std::make_shared
new
在列表中选择符合对象要求的最早的一个。
就其本身而言,string
几乎是一个库容器,一个字符容器,因此动态分配string
几乎从来都不是正确的选择。如果您希望避免复制,可以通过引用传递它,并使用std::move
转移所有权。