@@ -55,18 +55,15 @@ use crate::{fmt, ops, slice, str};
5555/// Passing a Rust-originating C string: 
5656/// 
5757/// ``` 
58- /// use std::ffi::{CString,  CStr} ; 
58+ /// use std::ffi::CStr; 
5959/// use std::os::raw::c_char; 
6060/// 
6161/// fn work(data: &CStr) { 
62- /// #   /* Extern functions are awkward in doc comments - fake it instead 
63- ///     extern "C" { fn work_with(data: *const c_char); } 
64- /// #   */ unsafe extern "C" fn work_with(s: *const c_char) {} 
65- /// 
62+ ///     unsafe extern "C" fn work_with(s: *const c_char) {} 
6663///     unsafe { work_with(data.as_ptr()) } 
6764/// } 
6865/// 
69- /// let s = CString::new("data data data data").expect("CString::new failed") ; 
66+ /// let s = c"Hello world!" ; 
7067/// work(&s); 
7168/// ``` 
7269/// 
@@ -384,13 +381,12 @@ impl CStr {
384381/// # Examples 
385382/// 
386383/// ``` 
387- /// use std::ffi::{ CStr, CString} ; 
384+ /// use std::ffi::CStr; 
388385/// 
389- /// unsafe { 
390- ///     let cstring = CString::new("hello").expect("CString::new failed"); 
391- ///     let cstr = CStr::from_bytes_with_nul_unchecked(cstring.to_bytes_with_nul()); 
392- ///     assert_eq!(cstr, &*cstring); 
393- /// } 
386+ /// let bytes = b"Hello world!\0"; 
387+ /// 
388+ /// let cstr = unsafe { CStr::from_bytes_with_nul_unchecked(bytes) }; 
389+ /// assert_eq!(cstr.to_bytes_with_nul(), bytes); 
394390/// ``` 
395391#[ inline]  
396392    #[ must_use]  
@@ -449,38 +445,60 @@ impl CStr {
449445/// behavior when `ptr` is used inside the `unsafe` block: 
450446/// 
451447/// ```no_run 
452- /// # #![allow(unused_must_use)] 
453448/// # #![expect(dangling_pointers_from_temporaries)] 
454- /// use std::ffi::CString; 
455- /// 
456449/// // Do not do this: 
457- /// let ptr = CString::new("Hello").expect("CString::new failed").as_ptr(); 
458- /// unsafe { 
459- ///     // `ptr` is dangling 
460- ///     *ptr; 
461- /// } 
450+ /// let ptr = std::ffi::CStr::from_bytes_with_nul( 
451+ ///     &"Hello world!" 
452+ ///         .to_uppercase() 
453+ ///         .chars() 
454+ ///         .map(|c| c.try_into().unwrap()) 
455+ ///         .chain(std::iter::once(0)) 
456+ ///         .collect::<Vec<u8>>(), 
457+ /// ) 
458+ /// .unwrap() 
459+ /// .as_ptr(); 
460+ /// // above CStr temporary was dropped and `ptr` is now dangling! 
461+ /// 
462+ /// // shows ptr is now garbage 
463+ /// assert_eq!( 
464+ ///     (0..) 
465+ ///         .map_while(|i| unsafe { 
466+ ///             let p = ptr.add(i); 
467+ ///             (*p != 0).then_some(*p as u8 as char) 
468+ ///         }) 
469+ ///         .collect::<String>(), 
470+ ///     "Hello world!".to_uppercase() 
471+ /// ); 
462472/// ``` 
463473/// 
464474/// This happens because the pointer returned by `as_ptr` does not carry any 
465- /// lifetime information and the `CString` is deallocated immediately after 
466- /// the `CString::new("Hello").expect("CString::new failed").as_ptr()` 
467- /// expression is evaluated. 
468- /// To fix the problem, bind the `CString` to a local variable: 
475+ /// lifetime information and the `CStr` is deallocated immediately after 
476+ /// the expression it is part of is evaluated. 
477+ /// To fix the problem, bind the `CStr` to a local variable: 
469478/// 
470479/// ```no_run 
471- /// # #![allow(unused_must_use)] 
472- /// use std::ffi::CString; 
473- /// 
474- /// let hello = CString::new("Hello").expect("CString::new failed"); 
475- /// let ptr = hello.as_ptr(); 
476- /// unsafe { 
477- ///     // `ptr` is valid because `hello` is in scope 
478- ///     *ptr; 
479- /// } 
480+ /// let c_str = std::ffi::CStr::from_bytes_with_nul( 
481+ ///     &"Hello world!" 
482+ ///         .to_uppercase() 
483+ ///         .chars() 
484+ ///         .map(|c| c.try_into().unwrap()) 
485+ ///         .chain(std::iter::once(0)) 
486+ ///         .collect::<Vec<u8>>(), 
487+ /// ) 
488+ /// .unwrap(); 
489+ /// // above CStr is now bound and will not be dropped immediately 
490+ /// let ptr = c_str.as_ptr(); 
491+ /// 
492+ /// assert_eq!( 
493+ ///     (0..) 
494+ ///         .map_while(|i| unsafe { 
495+ ///             let p = ptr.add(i); 
496+ ///             (*p != 0).then_some(*p as u8 as char) 
497+ ///         }) 
498+ ///         .collect::<String>(), 
499+ ///     "Hello world!".to_uppercase() 
500+ /// ); 
480501/// ``` 
481- /// 
482- /// This way, the lifetime of the `CString` in `hello` encompasses 
483- /// the lifetime of `ptr` and the `unsafe` block. 
484502#[ inline]  
485503    #[ must_use]  
486504    #[ stable( feature = "rust1" ,  since = "1.0.0" ) ]  
0 commit comments