Skip to content

Commit 677aa47

Browse files
committed
Document CStr::as_ptr dangers.
1 parent b1ae194 commit 677aa47

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

src/libstd/ffi/c_str.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,38 @@ impl CStr {
509509
/// The returned pointer will be valid for as long as `self` is and points
510510
/// to a contiguous region of memory terminated with a 0 byte to represent
511511
/// the end of the string.
512+
///
513+
/// **WARNING**
514+
///
515+
/// It is your responsibility to make sure that the underlying memory is not
516+
/// freed too early. For example, the following code will cause undefined
517+
/// behaviour when `ptr` is used inside the `unsafe` block:
518+
///
519+
/// ```no_run
520+
/// use std::ffi::{CString};
521+
///
522+
/// let ptr = CString::new("Hello").unwrap().as_ptr();
523+
/// unsafe {
524+
/// // `ptr` is dangling
525+
/// *ptr;
526+
/// }
527+
/// ```
528+
///
529+
/// This happens because the pointer returned by `as_ptr` does not carry any
530+
/// lifetime information and the string is deallocated immediately after
531+
/// the `CString::new("Hello").unwrap().as_ptr()` expression is evaluated.
532+
/// To fix the problem, bind the string to a local variable:
533+
///
534+
/// ```no_run
535+
/// use std::ffi::{CString};
536+
///
537+
/// let hello = CString::new("Hello").unwrap();
538+
/// let ptr = hello.as_ptr();
539+
/// unsafe {
540+
/// // `ptr` is valid because `hello` is in scope
541+
/// *ptr;
542+
/// }
543+
/// ```
512544
#[stable(feature = "rust1", since = "1.0.0")]
513545
pub fn as_ptr(&self) -> *const c_char {
514546
self.inner.as_ptr()

0 commit comments

Comments
 (0)