Builtin MemCpy Chk will always overflow destination buffer

时间:2017-06-09 12:53:06

标签: ios objective-c 64-bit nsdata memcpy

Updating my app from 32-bit to 64-bit.

According to the Apple Documentation floats are only 4 byte and I need to use CGFloat (8 byte)

I am using the memcpy to read in bytes. I have updated all my sizeof(float)s to sizeof(CGFloat).

But when I do I get the Semantic issue

__builtin___memcpy_chk will always overflow destination buffer. Expanded from macro memcpy

I updated my NSData readDataOfLenght to take sizeof(CGFloat) and it seems to work ok. Sometimes not all the data that is read in is correct.

I am afraid I am over my head in this and could use some help.

-(void) readByteData:(NSFileHandle *)fHandle Size:(NSInteger)byteSize
{
    [super readByteData:fHandle Size:byteSize];

    NSData *data = [fHandle readDataOfLength:sizeof(CGFloat)];
    float r;
    memcpy(&r, [data bytes], sizeof(CGFloat));
    self.radius = r;

    int nCGPointSize = sizeof(CGFloat) * 2;
    data = [fHandle readDataOfLength:nCGPointSize];
    float xy[2];
    memcpy(xy, [data bytes], nCGPointSize);
    self.centerPos = ccp(xy[0], xy[1]);

    data = [fHandle readDataOfLength:sizeof(CGFloat)];
    float start_angle;
    memcpy(&start_angle, [data bytes], sizeof(CGFloat));
    self.startAngle = start_angle;

    data = [fHandle readDataOfLength:sizeof(CGFloat)];
    float end_angle;
    memcpy(&end_angle, [data bytes], sizeof(CGFloat));
    self.endAngle = end_angle;

    data = [fHandle readDataOfLength:sizeof(int)];
    int d;
    memcpy(&d, [data bytes], sizeof(int));
    self.dir = d;

    flagClosed = YES;
}

1 个答案:

答案 0 :(得分:0)

这条指令:

float r;
memcpy(&r, [data bytes], sizeof(CGFloat));

告诉你的编译器:

  

sizeof(CGFloat)位置读取[data bytes](== 8个字节!)   并将它们写入r

r的大小只有4个字节!因此前4个字节写入r,接下来的4个字节写入{{1}后面的任何内容在内存中,这是不允许的。 r是一个简单的字节复制指令,它将任意数量的字节从内存位置A移动到内存位置B,它不能为您转换数据类型。如果您需要将memcpy值转换为CGFloat值,那么您实际上需要自己进行转换。

float

读取多个值时相同:

CGFloat bigR;
memcpy(&bigR, [data bytes], sizeof(bigR));
self.radius = (float)bigR;

演员表只是为了更清楚地说明转换发生的地方,大多数编译器也会在没有所有CGFloat bigXY[2]; data = [fHandle readDataOfLength:sizeof(bigXY)]; memcpy(bigXY, [data bytes], sizeof(bigXY)); self.centerPos = ccp((float)bigXY[0], (float)bixXY[1]); 演员表的情况下编译代码并且没有抱怨。

作为一般规则:

(float)

memcpy(dst, src, size) 绝不能大于内存size或内存src指向的内存。在您的情况下,dst总是大于指向的内存size

到目前为止,您的代码无法解释原因。但是,您实际上根本不需要使用dst,就好像您有一个已知数据类型的多个值的内存块,当然您可以直接访问该内存而无需将其复制到任何地方:

memcpy

等等。但这是非常低效的,因为你似乎总是期望一些没有可选值的固定大小结构,那么为什么不把它作为结构来阅读呢?这样,您只需要一次I / O访问即可读取所有内容,系统只能创建一个NSData * data = [fHandle readDataOfLength:sizeof(CGFloat)]; if (!data) { // ... handle errorr ... } const CGFloat * cgfloatsInData = (const CGFloat *)[data bytes]; self.radius = (float)cgfloatsInData[0]; data = [fHandle readDataOfLength:sizeof(CGFloat) * 2]; if (!data) { // ... handle errorr ... } const CGFloat * cgfloatsInData = (const CGFloat *)[data bytes]; self.centerPos = ccp((float)cgfloatsInData[0], (float)cgfloatsInData[1]); 对象。

NSData