在x86_64上Objective-C的不稳定内存行为

时间:2014-01-16 20:14:25

标签: objective-c x86-64 foundation

在测试我的开源项目MHTextSearch时,我遇到了一个奇怪的问题。在第169 of MHTextIndex.m行:

uint64_t maxLength = [indexedString maximumLengthOfBytesUsingEncoding:encoding];
// some code

for (...) {

    [indexedString getBytes:keyPtr
                  maxLength:maxLength
                 usedLength:&usedLength
                   encoding:encoding
                    options:NSStringEncodingConversionAllowLossy
                      range:subRange
             remainingRange:NULL];

    // some more code
}

其他任何地方都没有修改maxLength。在第二次迭代中,maxLength等于0,无论其先前的值是什么。如果我在其上设置观察点,我会在-[NSString getBytes:maxLength:usedLength:encoding:options:range:remainingRange:]处看到它在

处发生变化
0x100038d19:  movq   -0x30(%rbp), %rdx
0x100038d1d:  movq   %rdx, (%rsi)
0x100038d20:  testq  %rcx, %rcx            << this instruction

关于这一点非常奇怪的是它只发生在x86_64体系结构上,如果我像这样更改代码就可以修复它

uint64_t maxLength = [indexedString maximumLengthOfBytesUsingEncoding:encoding];
uint64_t strLength = maxLength;
// some code

for (...) {

    [indexedString getBytes:keyPtr
                  maxLength:strLength
                 usedLength:&usedLength
                   encoding:encoding
                    options:NSStringEncodingConversionAllowLossy
                      range:subRange
             remainingRange:NULL];

    // some more code
}

使用此代码,maxLength仍会在同一指令处更改为0 ,但strLength保持一致,因此效果将被删除。

怎么回事?

1 个答案:

答案 0 :(得分:2)

usedLength的类型错误。它被声明为uint32_t。但是,它应该声明为NSUInteger,在32位体系结构上为32位,在64位体系结构上为64位。