2017-11-14 11 views
1

次の単体テストは、一部のUnsafePointerが他と同じように常に失敗します。この動作は少なくとも3つの文字列で観察されます。 High Sierra Version 10.13.1(17B48)でXcodeバージョン9.1(9B55)を使用しています。UnsafePointer <Int8>が動作しない

func testUnsafePointer() { 
    let a = "aaa" 
    let b = "bbb" 
    let c = "ccc" 

    let ua = UnsafePointer<Int8>(a) 
    let ub = UnsafePointer<Int8>(b) 
    let uc = UnsafePointer<Int8>(c) 

    print("a: '\(a)', ua: '\(ua)'") 
    print("b: '\(b)', ub: '\(ub)'") 
    print("c: '\(c)', uc: '\(uc)'") 

    XCTAssertTrue(ua != ub) 
    XCTAssertTrue(ub != uc) 
    XCTAssertTrue(uc != ua) 
} 

プリントアウトは、この

a: 'aaa', ua: '0x000060c000056a30' 
b: 'bbb', ub: '0x00006080000530d0' 
c: 'ccc', uc: '0x00006080000530d0' 

NBに似ています。迅速な遊び場では、すべてが大丈夫です。 UnsafePointer

init(_ other: UnsafePointer<Pointee>) 

イニシャライザが呼び出され

let ua = UnsafePointer<Int8>(a) 

+0

を'あなたが思っていることをやってはいけません - Swiftは、指定された文字列のヌルで終了するUTF-8バイトで新しいバッファを作成し、そのバッファへのポインタを与えます。コールが終了した後にバッファが割り当て解除されるため、ぶら下がったポインタが残されます。したがって、同じ値を共有するポインタの問題ではありません。しかし、彼らはポインタをぶら下げているので、それらを逆参照しようとすることは*未定義の動作*です。あなたがここでやろうとしていることは、確かにそれについて行く正しい方法ではありません。 – Hamish

+0

@Hamishこれは動作を説明しています。私が意図したのは、このシグネチャを持つC関数に素早い文字列を渡すことです:void cfunc(const char * a、const char * b、const char * c)。しかし、このcfuncでは、最初の文字列は問題なく、他の文字列はガベージです。私はUnsafePointer変換でこのc関数を呼び出します。 – swift616

+2

@ swift616: 'cfunc(a、b、c)'を呼び出すだけで、コンパイラは自動的に変換に必要なコードを作成します。 –

答えて

2

。私。 スウィフトStringを、UnsafePointer<Int8> 引数を取る関数に渡しています。この場合、の一時的な文字列表現が作成され、関数に渡されます。 はString value to UnsafePointer<UInt8> function parameter behaviorです。一時的なC文字列が機能 呼び出しの間のみ有効で、かつリターンで、メモリがuaによって を指摘はまだそのC文字列(または任意の有効なデータ)が含まれていることが保証されていないことを

。また、

let ua = UnsafePointer<Int8>(a) 
let ub = UnsafePointer<Int8>(b) 
let uc = UnsafePointer<Int8>(c) 

は、その場合には、一時的なC列に同じ記憶域を使用することができ、あなたが観察されるように、ポインタが等しくなる 。あなたの意図はconst char *引数を取るC関数を呼び出すことである場合


、あなたは単にスウィフトの文字列を渡すことができます。 String value to UnsafePointer<UInt8> function parameter behaviorで説明したように、コンパイラ は、(関数呼び出しの持続時間のために再び有効)C文字列表現を 作成するために必要なコード、 を挿入します:

UnsafePointer (a)は `ほぼ確実doesnの
let a = "aaa" 
let b = "bbb" 
let c = "ccc" 

cfunc(a, b, c) 
+0

これは簡単です:) Thx – swift616

関連する問題