[英]-[NSInputStream read:maxLength:] throws an exception saying length is too big, but it isn't
I use an NSInputStream
to read data from a file. 我使用NSInputStream
从文件中读取数据。 It will crash if maxLength
is greater than 49152. 如果maxLength
大于49152,它将崩溃。
When it crashes -- sometimes, but not every time, it gives this message: 当它崩溃时 - 有时候,但不是每次都崩溃,它会给出这样的信息:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSConcreteData initWithBytes:length:copy:freeWhenDone:bytesAreVM:]: absurd length: 4294967295, maximum size: 2147483648 bytes' ***由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:'*** - [NSConcreteData initWithBytes:length:copy:freeWhenDone:bytesAreVM:]:荒谬长度:4294967295,最大大小:2147483648字节'
From my calculation, 524288 is still less than that maximum, and can fit in the return value. 根据我的计算,524288仍然小于该最大值,并且可以适合返回值。 What did I miss? 我错过了什么?
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode)
{
case NSStreamEventHasBytesAvailable:
{
NSInteger bufferSizeNumber = 524288; //this one will crash.
// NSInteger bufferSizeNumber = 491520; // this one will work.
uint8_t buf[bufferSizeNumber];
unsigned int len = 0;
len = [_stream read:buf maxLength:bufferSizeNumber]; //crashing at this line
// more code ...
}
// more code...
}
}
Edit: (I think this is critical part of that behavior) 编辑:(我认为这是该行为的关键部分)
If I "start" in the background thread then the bufferSizeNumber behaves as described above. 如果我在后台线程中“启动”,则bufferSizeNumber的行为如上所述。 But if I "start" in the main thread, the bufferSizeNumber can go upto 943713 before it crashes. 但是如果我在主线程中“启动”,则bufferSizeNumber在崩溃之前可以达到943713。
- (void)start
{
_stream.delegate = self;
[_stream scheduleInRunLoop:[NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
[_stream open];
[[NSRunLoop currentRunLoop] run];
}
Your problem is a so called "stack overflow" (you might have heard this before). 你的问题是所谓的“堆栈溢出”(你可能以前听过这个)。
Your method allocates a buffer on the stack using a variable length array: 您的方法使用可变长度数组在堆栈上分配缓冲区:
uint8_t buf[bufferSizeNumber];
When the size of the buffer is so large that it overflows the size of the current stack the behavior is undefined. 当缓冲区的大小太大以至于溢出当前堆栈的大小时,行为是不确定的。 Undefined behavior might result in a crash or just work as expected: just what you are observing. 未定义的行为可能会导致崩溃或只是按预期工作:只是您正在观察的内容。
512kB is a huge buffer, especially on iOS where background threads get a stack of exactly this size. 512kB是一个巨大的缓冲区,特别是在iOS上,后台线程的堆栈大小正是这样。
You should allocate it on the heap: 你应该在堆上分配它:
NSInteger bufferSizeNumber = 524288;
NSMutableData *myBuffer = [NSMutableData dataWithLength:bufferSizeNumber];
uint8_t *buf = [myBuffer mutableBytes];
unsigned int len = 0;
len = [_stream read:buf maxLength:bufferSizeNumber];
// more code ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.