说我有类似的东西
extern "C" void make_foo (char** tgt) {
*tgt = (char*) malloc(4*sizeof(char));
strncpy(*tgt, "foo", 4);
}
int main() {
char* foo;
make_foo(&foo);
std::string foos{{foo}};
free(foo);
...
return 0;
}
现在,我想避免使用然后删除foo
缓冲区。即,我想将foos
的初始化更改为
std::string foos{{std::move(foo)}};
并且不使用明确的free
。
事实证明这实际上是编译并且似乎有效,但我对它有一种相当可疑的感觉:它是否实际上移动了C定义的字符串并正确释放存储?或者只是忽略std::move
并在foo
指针超出范围后泄漏存储空间?
并不是我太担心额外的副本,但我想知道是否可以用现代的移动语义风格来写这个。
答案 0 :(得分:3)
构造字符串,其内容已初始化为,副本为 s指向的以null结尾的字符串。。的长度 字符串由第一个空字符决定。行为是 如果s没有指向至少一个数组,则为undefined Traits :: length(s)CharT的+1个元素,包括s是a的情况 空指针。
您的C字符串已被复制(此处std::move
无关紧要),因此您可以在free
上致电foo
。
std::string
永远不会拥有所有权。
答案 1 :(得分:2)
指针没有任何特殊的移动语义。 x = std::move(my_char_ptr)
与x = my_char_ptr
相同。在这方面,他们 ,例如,std::vector
,其中移动会占用分配的空间。
但是,在你的情况下,如果你想保留现有的堆缓冲区并将它们视为字符串 - 它不能使用std::string
,因为它们不能构造为现有缓冲区的包装器(以及那里的小字符串优化等)。相反,请考虑实施自定义容器,例如带有一些字符串数据缓冲区(std::vector<char>
)和一个std::vector<std::string_view>
,其元素指向该缓冲区。