简体   繁体   English

- [NSInputStream read:maxLength:]抛出一个异常,说长度太大,但事实并非如此

[英]-[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.

相关问题 NSInputStream读取:maxlength:返回的字节数比maxlength多 - NSInputStream read: maxlength: returning way more bytes than maxlength [(NSInputStream *)stream read:buf maxLength:1024]; 回报非常巨大的价值 - [(NSInputStream *)stream read:buf maxLength:1024]; returns very huge value 当-[NSInputStream read:maxLength:]返回0时,它在Apple Document中是否模棱两可? - Is it ambiguous in Apple Document when -[NSInputStream read:maxLength:] return 0? 无法从NSInputStream读取自定义文件 - Can't read custom file from NSInputStream 如何将NSInputStream转换为NSString或如何读取NSInputStream - How to convert NSInputStream to NSString or how to read NSInputStream 如何使用UTF-8读取NSInputStream? - How to read a NSInputStream with UTF-8? 如果[nsInputStream close]被另一个线程调用,是否应该返回[nsInputStream read:…]? - Should [nsInputStream read:…] return if [nsInputStream close] is called by another thread? 无法使用NSInputStream从iOS客户端读取Java服务器的响应 - Can't read response from Java server in iOS client using NSInputStream 使用NSOutputstream和NSInputstream写入和读取每个间隔 - Use NSOutputstream and NSInputstream to write and read every interval NSInputStream包装器,用于通过指定的分隔符读取字符串 - NSInputStream wrapper to read strings by specified delimiter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM