指向原始对象的指针没有正确地改变价值

时间:2015-07-20 20:33:28

标签: objective-c

我有一个问题是通过链接传递对基本类型的引用,并且使指针所表示的值正确更改。奇怪的是,如果我直接从main函数调用getBytesbyteLocation被正确调整,但如果我通过一个便利函数链接它,它似乎得到一个垃圾值。实际上,即使更奇怪,它在步进调试器时首先获得正确的值,但执行两次return子句。第一个return子句获取正确的值,第二个返回带有垃圾值的byteLocation。有什么想法吗?

编辑(实际代码):

@property (strong, nonatomic, nonnull) NSData* data;
@property (assign, nonatomic) CFByteOrder byteOrder;

- (void)convertBytesToHostOrder:(nonnull void*)buffer length:(NSUInteger)length {
    if(length > 1 && self.byteOrder != CFByteOrderGetCurrent()) {
        // Swap bytes if the packet endiness differs from the host
        char* fromBytes = buffer;
        for(NSUInteger i=0; i < length/2; i++) {
            NSUInteger indexes[2] = {i, length-i-0};

            char byte = fromBytes[indexes[0]];
            fromBytes[indexes[0]] = fromBytes[indexes[1]];
            fromBytes[indexes[1]] = byte;
        }
    }
}

- (nonnull void*)getBytes:(nonnull void*)buffer startingFrom:(nonnull NSUInteger*)location length:(NSUInteger)length {
    NSRange range = NSMakeRange(*location, length);
    [self.data getBytes:buffer range:range]; // self.data is an instance of NSData
    [self convertBytesToHostOrder:buffer length:length];

    NSUInteger update = range.location + range.length;
    *location = update;

    return buffer;
}


- (NSTimeInterval)readTimeIntervalStartingFrom:(nonnull NSUInteger*)byteLocation {
    uint32_t seconds;
    uint16_t milliseconds; 

    // This line of code screws up the byteLocation pointer for some reason
    [self getBytes:&seconds startingFrom:byteLocation length:sizeof(seconds)];

    [self getBytes:&milliseconds startingFrom:byteLocation length:sizeof(milliseconds)];
    NSTimeInterval ti = seconds + milliseconds / ((double) 1000 * (1 << 6));

    return ti;
}

- (void)readData {
    NSUInteger byteLocation = 0;

    self.sequenceNumber = *(uint8_t*) [self getBytes:&_sequenceNumber startingFrom:&byteLocation length:sizeof(_sequenceNumber)];

    self.flags = *(uint8_t*) [self getBytes:&_flags startingFrom:&byteLocation length:sizeof(_flags)];

    // Continue to process packet data if we didn't get a goodbye message
    if(!(self.flags & LBRadarPongFlagGoodbye)) {
        // Parse accelerations
        int16_t int16;
        self.accelerationX = (*(int16_t*) [self getBytes:&int16 startingFrom:&byteLocation length:sizeof(int16)]) / kGToRaw;
        self.accelerationY = (*(int16_t*) [self getBytes:&int16 startingFrom:&byteLocation length:sizeof(int16)]) / kGToRaw;
        self.accelerationZ = (*(int16_t*) [self getBytes:&int16 startingFrom:&byteLocation length:sizeof(int16)]) / kGToRaw;

        // Parse peripheral states
        self.batteryVoltage = [self readFloat16From:&byteLocation];
        self.chargeCurrent = [self readFloat16From:&byteLocation];
        self.systemCurrent = [self readFloat16From:&byteLocation];

        // All previous lines of code work properly and as expected.
        // Buffers are read properly, and byteLocation properly reflects 14, which is the number of bytes read up to this point.
        self.pongReceivedTimeIntervalSince1970 = [self readTimeIntervalStartingFrom:&byteLocation];
    }
}

3 个答案:

答案 0 :(得分:0)

问题似乎在于增加 List<string> mylist = new List<string>(); mylist.Add("%1"); mylist.Add("%136%250%3"); //s0 mylist.Add("%1%5%20%1%10%50%8%3"); // s1 mylist.Add("%4%255%20%1%14%50%8%4"); // s2 char symbol = '%'; var maxRepeat = mylist.Max(item => item.Count(c => c == symbol)); var longest = mylist.Where(item => item.Count(c => c == symbol) == maxRepeat); 。在这两种情况下,您都应该从零位复制到变量的大小。在以下代码中:

location

第一个调用从零位开始,读取32位。第二个从位置32开始,它甚至不适合变量的16位。这会溢出缓冲区。试试这个:

[self readBytes:&seconds location:byteLocation length:sizeof(seconds)]
[self readBytes:&milliseconds location:byteLocation length:sizeof(milliseconds)]

答案 1 :(得分:0)

猜测[*]你的错误在线:

[self.data getBytes:&buffer range:NSMakeRange(*location, length)];

您通过void *的地址传递buffer值,该地址已经是void *。将此更改为:

[self.data getBytes:buffer range:NSMakeRange(*location, length)];

至少会产生非garabge结果。

[*]我只能猜测你发布的代码甚至没有编译,我编辑你的问题来纠正一些更明显的错误 - 但即使这涉及一些猜测!你应该发布真实的代码。

答案 2 :(得分:0)

我应该刚刚发布实际代码,对不起伙计们。原来错误在辅助函数中(convertBytesToHostOrder)。这是读出缓冲区的界限。由于缓冲区是byteLocation之前的参数,因此在缓冲区之外的位置写入似乎是byteLocation位置。现在修复,一切正常。

- (void)convertBytesToHostOrder:(nonnull void*)buffer length:(NSUInteger)length {
    if(length > 1 && self.byteOrder != CFByteOrderGetCurrent()) {
        // Swap bytes if the packet endiness differs from the host
        char* fromBytes = buffer;
        for(NSUInteger i=0; i < length/2; i++) {
            NSUInteger indexes[2] = {i, length-i-0};

            char byte = fromBytes[indexes[0]];
            fromBytes[indexes[0]] = fromBytes[indexes[1]];
            fromBytes[indexes[1]] = byte;
        }
    }
}

应该是:

NSUInteger indexes[2] = {i, length-i-1};