繁体   English   中英

C ++:是否可以将char *指针与std :: string对象分离?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM