[英]C++: Is it possible to detach the char* pointer from an std::string object?
我正在使用std :: string类型进行字符串操作。
但是,有时即使原始的std :: string对象被破坏后,我仍需要保留原始的char *指针(是的,我知道char *指针引用了HEAP,最终必须将其丢弃)。
但是,看起来没有办法将原始指针从字符串中分离出来吗?
也许我应该使用另一个字符串实现?
谢谢。
编辑
亲爱的,请不要将分离与复制混淆。 分离的本质是使字符串对象放弃其对基础缓冲区的所有权。 因此,如果字符串具有detach
方法,则其语义将如下所示:
char *ptr = NULL;
{
std::string s = "Hello world!";
ptr = s.detach(); // May actually allocate memory, if the string is small enough to have been held inside the static buffer found in std::string.
assert(s == NULL);
}
// at this point s is destroyed
// ptr continues to point to a valid HEAP memory with the "Hello world!" string in it.
...
delete ptr; // need to cleanup
不,不可能分离std::string::c_str()
返回的指针。
解决方案:创建该字符串的只读副本,并确保该副本的生存时间至少与需要char *指针一样长。 然后在该副本上使用c_str()
,它会一直有效,只要您想要。
如果那不可能,那么您也将无法释放char*
。 将指针包装在RAII结构中的任何尝试都只会重新发明std :: string的一部分。
std::string
通过std:allocator
(或模板参数)进行std:allocator
。 即使您可以分离原始存储,也必须通过std::allocator
释放它。 您当然希望RAII类能够正确地做到这一点。
幸运的是,标准库中已经存在这样的RAII类。 它称为std::string
。
因此,最接近“分离”功能的是swap
。 它从字符串中分离资源,并以某种形式存储它们,以便以后可以从中正确释放它们(即,另一个字符串)。 在C ++ 11中,移动分配也可以做到这一点。
std::string raii_for_ptr;
const char *ptr = NULL;
{
std::string s = "Hello world!";
raii_for_ptr.swap(s); // or raii_for_ptr = std::move(s)
ptr = raii_for_ptr.c_str();
assert(s == "");
}
// no need to cleanup
如果您的目标是为自己创建需要对某些对象调用delete
的需求,那么(a)这是荒谬的,因此(b)标准库将无济于事。 无论如何,您可能需要delete[]
而不是delete
。 但是由于字符串不是(直接)分配给new
,因此认为您可以占用它们的内存并使用delete[]
(直接)释放它是不合适的。
因此,如果您的实际情况是需要将某个预先存在的API传递给缓冲区,该缓冲区将通过delete[]
释放,那么您将必须复制一个副本,就像您需要传递某些预先存在的API一样一个可以用free
释放的缓冲区。
使用c_str()
将字符串复制到C样式字符串中。 然后使用strcpy()
您可以将字符串复制到新的char数组中。
std::string s = "My string";
char *a = new char[s.size()+1];
a[s.size()]=0;
memcpy(a,s.c_str(),s.size());
您可以使用2种东西,具体取决于您的需求。 string :: c_str()会将字符复制到C字符串中,然后您可以根据需要使用它。 std :: data()将返回指向该字符串的指针,但是存在两个问题:a)它不是像C字符串一样终止为NULL,并且b)当删除std :: string时,它将消失。 因此,删除原始对象后,它不会停留在周围。
由于您应该始终知道谁拥有内存的特定部分,因此更改字符串所有权的唯一方法是复制它。 最简单的方法是将字符串分配给另一个std :: string变量。 如果所有权更改非常频繁(或者您根本无法明确确定哪个特定对象是所有者),则需要使用支持引用计数的字符串的另一种实现(或std :: string的包装器),因此您不必须一直分配新的内存。
U可以如下使用它:
std::string str = "abcd";
char* cStr = str.c_str();
谢谢...:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.