Skip to content

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

Closed
wants to merge 2 commits into from
Closed

impl Clone for CString #11840

wants to merge 2 commits into from

Conversation

emberian
Copy link
Member

No description provided.

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_ }
Copy link
Member

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?

Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Contributor

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());
}

bors added a commit that referenced this pull request Feb 1, 2014
@bors bors closed this Feb 2, 2014
bors added a commit to rust-lang-ci/rust that referenced this pull request Dec 1, 2023
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants