简体   繁体   English

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

[英]C++: Is it possible to detach the char* pointer from an std::string object?

I am using the std::string type for my string manipulations. 我正在使用std :: string类型进行字符串操作。

However, sometimes I need to keep the raw char* pointer, even after the original std::string object is destroyed (yes, I know the char* pointer references the HEAP and must eventually be disposed of). 但是,有时即使原始的std :: string对象被破坏后,我仍需要保留原始的char *指针(是的,我知道char *指针引用了HEAP,最终必须将其丢弃)。

However, looks like there is no way to detach the raw pointer from the string or is it? 但是,看起来没有办法将原始指针从字符串中分离出来吗?

Maybe I should use another string implementation? 也许我应该使用另一个字符串实现?

Thanks. 谢谢。

EDIT 编辑

Folks, please do not confuse detaching with copying. 亲爱的,请不要将分离与复制混淆。 The essence of detaching is for the string object to relinquish its ownership on the underlying buffer. 分离的本质是使字符串对象放弃其对基础缓冲区的所有权。 So, had the string had the detach method, its semantics would be something like this: 因此,如果字符串具有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

No, it is not possible to detach the pointer returned by std::string::c_str() . 不,不可能分离std::string::c_str()返回的指针。

Solution: Make a read-only copy of the string, and ensure that that copy lives at least as long as you need the char* pointer. 解决方案:创建该字符串的只读副本,并确保该副本的生存时间至少与需要char *指针一样长。 Then use c_str() on that copy, and it will be valid as long as you want. 然后在该副本上使用c_str() ,它会一直有效,只要您想要。

If that is not possible, then you won't be able to release the char* either. 如果那不可能,那么您也将无法释放char* And any attempt to wrap that pointer in a RAII construction, will only re-invent parts of std::string. 将指针包装在RAII结构中的任何尝试都只会重新发明std :: string的一部分。

std::string allocates through std:allocator (or a template parameter). std::string通过std:allocator (或模板参数)进行std:allocator Even if you could detach the raw storage, you'd have to free it through std::allocator too. 即使您可以分离原始存储,也必须通过std::allocator释放它。 And you would of course want a RAII class to do that correctly. 您当然希望RAII类能够正确地做到这一点。

Fortunately, there already is just such a RAII class in the standard libraries. 幸运的是,标准库中已经存在这样的RAII类。 It's called std::string . 它称为std::string

The closest thing to a "detach" function, therefore, is swap . 因此,最接近“分离”功能的是swap It detaches the resources from a string, and stores them in a form from which they can be correctly freed later (ie, another string). 它从字符串中分离资源,并以某种形式存储它们,以便以后可以从中正确释放它们(即,另一个字符串)。 In C++11, move assignment does that too. 在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

If your objective is to create for yourself the need to call delete on something, then (a) that's absurd, and hence (b) the standard libraries won't help you. 如果您的目标是为自己创建需要对某些对象调用delete的需求,那么(a)这是荒谬的,因此(b)标准库将无济于事。 Anyway, you'd probably need delete[] rather than delete . 无论如何,您可能需要delete[]而不是delete But since strings are not (directly) allocated with new , it's not appropriate to think you can take their memory and free it (directly) with delete[] . 但是由于字符串不是(直接)分配给new ,因此认为您可以占用它们的内存并使用delete[] (直接)释放它是不合适的。

So, if your real situation is that you need to pass some pre-existing API a buffer that will be freed with delete[] , then you'll have to take a copy, just as if you needed to pass some pre-existing API a buffer that will be freed with free . 因此,如果您的实际情况是需要将某个预先存在的API传递给缓冲区,该缓冲区将通过delete[]释放,那么您将必须复制一个副本,就像您需要传递某些预先存在的API一样一个可以用free释放的缓冲区。

Use c_str() to copy the string into C style string. 使用c_str()将字符串复制到C样式字符串中。 And then use strcpy() 然后使用strcpy()

You can copy your string to a new array of char. 您可以将字符串复制到新的char数组中。

std::string s = "My string";
char *a = new char[s.size()+1];
a[s.size()]=0;
memcpy(a,s.c_str(),s.size());

There are 2 things you can use, depending on what you need. 您可以使用2种东西,具体取决于您的需求。 string::c_str () will copy the characters into a C string you can then use for whatever you need. string :: c_str()会将字符复制到C字符串中,然后您可以根据需要使用它。 std::data () will return a pointer to the string, but there are 2 issues: a) it is not NULL terminated like a C string, and b) it will go away when the std::string is deleted. std :: data()将返回指向该字符串的指针,但是存在两个问题:a)它不是像C字符串一样终止为NULL,并且b)当删除std :: string时,它将消失。 So it doesn't stick around after you delete the original object. 因此,删除原始对象后,它不会停留在周围。

Since you should always know who owns a particular section of memory the only way to change ownership of a string is to copy it. 由于您应该始终知道谁拥有内存的特定部分,因此更改字符串所有权的唯一方法是复制它。 The simplest way to do this is to just assign the string to another std::string variable. 最简单的方法是将字符串分配给另一个std :: string变量。 If the ownership changes very often (or you simply cannot clearly determine which specific object is the owner) you'd want to use another implementation of string (or a wrapper for std::string) that supports reference counting, so you don't have to allocate new memory all the time. 如果所有权更改非常频繁(或者您根本无法明确确定哪个特定对象是所有者),则需要使用支持引用计数的字符串的另一种实现(或std :: string的包装器),因此您不必须一直分配新的内存。

U can use it as follows: U可以如下使用它:

std::string str = "abcd";
char* cStr = str.c_str();

Thanks...:) 谢谢...:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以从C ++中的std :: string中分离缓冲区吗? - Can I detach the buffer from a std::string in C++? 在C ++中从std :: string转换为char * - Converting from std::string to char * in C++ C ++:指向std :: string转换的char指针是否复制内容? - C++ : Does char pointer to std::string conversion copy the content? 我们可以从char指针创建一个C ++字符串对象,将字符串对象上的操作反映到源char指针吗? - Can we create a C++ string object from char pointer where the operations on the string object reflects to the source char pointer? C++ 转一个 std::tuple<char, char, char> 进入 std::string?</char,> - C++ turn a std::tuple<char, char, char> into a std::string? 如何从 C++ std::vector 转移所有权<char>到一个字符 * 指针 - how to transfer ownership from a c++ std::vector<char> to a char *pointer C ++如何从std :: string中删除\\ 0 char - C++ How to remove \0 char from std::string 是否有可能将指针作为std :: vector中的连续内存片段 <char> 在C ++中? - Is it possible to get the pointer the continous memory fragment in a std::vector<char> in C++? C++:是否可以从重载 &lt;&lt; 运算符的 object 中获取 std::string ? - C++: Is it possible to get a std::string out of an object that overloads the << operator? C ++ const char *转换为std :: string& - C++ const char* to std::string &
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM