-
Notifications
You must be signed in to change notification settings - Fork 13.3k
impl Clone for CString #11840
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
impl Clone for CString #11840
Conversation
unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, self.len()); } | ||
CString { buf: buf as *libc::c_char, owns_buffer_: true } | ||
} else { | ||
CString { buf: self.buf, owns_buffer_: self.owns_buffer_ } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that we'll want to copy the ownership here. If I clone an object I'd expect to get a totally independent copy of the original object (to send around etc).
Dropping a CString after the malloc buffer has gone away is a real issue today, but this doesn't make things worse, so perhaps that concept doesn't matter too much?
What do others think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. Copying a CString
should copy the underlying buffer always.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was discussed in irc. I originally had it always do a deep clone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cmr: Not much of a discussion there. I don't see any resolution, just kimundi saying that &T
gets cloned to &T
.
However, it seems to me that doing a shallow clone in the non-owning case is unsafe. If I have a function fn foo(f: |c: &CString|)
and it calls the closure with a non-owned CString, the closure can make a clone of that and store it somewhere accessible from outside the closure. Then when the closure returns, the underlying buffer may be freed, or reused, or whatever else, but my code still has access to it via the clone.
fn foo(f: |c: &CString|) {
let s = ~"test";
let c = s.to_c_str();
// give the closure a non-owned CString
let mut c_ = c.with_ref(|c| unsafe { CString::new(c, false) } );
f(&c_);
// muck with the buffer for later printing
c_.with_mut_ref(|c| unsafe { *c = 'X' as libc::c_char } );
}
fn main() {
let mut c_: Option<CString> = None;
foo(|c| {
c_ = Some(c.clone());
println!("cstr: {:?}", c.as_bytes());
});
let c_ = c_.unwrap();
println!("c_: {:?}", c_.as_bytes());
}
Clone tests
…cfg, r=blyxyas Improve maybe misused cfg Follow-up of the improvements that were suggested to me in rust-lang/rust-clippy#11821: * I unified the output to use the same terms. * I updated the code to prevent creating a new symbol. r? `@blyxyas` changelog: [`maybe_misued_cfg`]: Output and code improvements
No description provided.