2016-04-03 18 views
1

1つのスライスを2つにすることができる非常に良いsplit_at_mut関数があります... 私は元の配列に再び戻ることができるようにその操作を元に戻す方法があります - 私はそれらが連続していることを仮定することができますメモリ内の質問があるRust:split_at_mut(つまりjoin_mut)の反対側はありますか?

(私はちょうどそれらを分割するため):

fn main() { 
    let mut item : [u8;32] = [0u8;32]; 
    let (mut first, mut second) = item[..].split_at_mut(16); 
    first[0] = 4; 
    second[0] = 8; 
    let mut x = first.join_mut(first, second); // <-- compile error 
    assert_eq(x[16], 8); 
} 
+3

私は理解していません。 'first'と' second'は 'item'の単なるスライスなので、' item'自体をそれらに戻そうとせずに使ってみましょう。 'assert_eq!(item [16]、8);のように' x'を 'item'と置き換えると、テストに合格します(実際にやっていることを単純化したものです) ? –

+1

この単純化された例では合理的なことです。しかし、あなたが何らかのアロケータを作っていると仮定し、2つの結合されていないスライスをクライアントに返して、どちらも解放されたので、より大きなスライスに結合できるようにしたいと考えてください。その場合、split_at_mutから他のスライスを借りて何十個ものスライスがあるので、各スライスの元の位置が失われたり元のアイテムが失われることになります。 – hellcatv

+0

問題の正確な状況は次のとおりです。https://github.com /dropbox/rust-alloc-no-stdlib/blob/master/src/stack_allocator.rs free_cellには、 'mutスライスがシステムに返されていて、他のフリースライスと再結合できるかどうかを確認するのがいいでしょう。それらを統一するためのスライス – hellcatv

答えて

4

は、標準ライブラリにはそのような機能はありません、それはかなりニッチがあり、おそらく以来:そうのようjoin_mutに似たものがあります通常、最初のケースで分割されたスライスを使用して解決することができます。

言われているように、少し安全ではあるが、この機能を実装することは可能です。

fn join_mut<'a, T>(first: &'a mut [T], second: &'a mut [T]) -> Option<&'a mut [T]> { 
    let fl = first.len(); 
    if first[fl..].as_mut_ptr() == second.as_mut_ptr() { 
     unsafe { 
      Some(::std::slice::from_raw_parts_mut(first.as_mut_ptr(), fl + second.len())) 
     } 
    } 
    else { 
     None 
    } 
} 

Playground

+0

これらが実際には同じスライスのものであった場合、このコードは私にとって完璧な意味を持ちます。しかし、C++では、異なる配列からのポインタの等価性を比較することは未定義の動作です(私は分割されたアーキテクチャを補うと思います)。これは錆の中で定義された行動ですか? – hellcatv

+0

C++でポインターを比較するための未定義の振る舞いになることはありません。 Rustがそれをどのように定義しているかわからないので、もっと精通した人がその質問に答える必要があるのではないかと恐れています。それは本当に私にとっては直感的ではないようですが、私のコードには実際には定義されていない動作が含まれているかもしれません。 – Mar

+1

@hellcatv私は<, >のために不特定であることを言うこの質問を見つけたhttp://stackoverflow.com/questions/4909766/is-it-unspecified-behavior-to-compare-pointers-to-different-arrays-for-equalityなどが、==と!=は定義された結果を返すので、少なくともC++の場合、2つのポインタが等しいかどうかをチェックするときには未定義の動作はないと思います。おそらく、錆はこれを不特定にするものではない。 – Mar

関連する問題