2

我的代码中发生了一些奇怪的事情。基本上我正在做网络流应用程序,将一些数据传输到 iOS 上的环形缓冲区内存中,然后读取内存。我正在获取EXC_BAD_ACCESS一些未确定数量的数据。所以我启用 NSZombieEnabledNSAutoreleaseFreedObjectCheckEnabled设置了malloc_error_break并且能够查明错误的原因。

MainClass有财产(也尝试过强参考,相同的行为)

@property (nonatomic, 保留) RingBuffer *readBuffer;

RingBuffer类中,我将缓冲区大小初始化为:

-(id) initWithSize: (NSInteger) size
{
    self = [super init];
    m_size = size;
    buffer = (unsigned char *)calloc(m_size, sizeof(unsigned char));
    overflow = FALSE;
    m_tail = 0;
    m_head = 0;
    error = 0;
    return self;
}

之后,我使用 push 方法在 ringbuffer 中插入数据

- (void) push: (unsigned char) byte
{
    if (m_head == m_size && overflow == FALSE) {
        m_head = 0;
        overflow = TRUE;
        }
    buffer[m_head] = byte;
    m_head ++;
    if (overflow) m_tail++;
    if (m_tail == m_size) m_tail = 0;
}

如果我删除推送调用,应用程序将不会崩溃。如果调用推送调用,它会在一段时间后崩溃。有时我得到alloc: *** error for object 0x1cad3404: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug......有时它只是 EXC_BAD_ACCESS。

基本上,我不明白为什么会导致这个问题?ARC是否有可能释放了被调用的内存?

4

2 回答 2

2

ARC是否有可能释放了被调用的内存?

不,那是不可能的。ARC 是 Automatic Reference Counting 的缩写,是一种编译器功能,如果启用,它可以通过将释放、保留和自动释放内存调用直接插入到编译代码中来提供 Objective C 对象的自动内存管理。因为buffer不是Objective C 对象,而是指向堆上已分配内存块的指针,ARC 不会释放该内存块。您有义务自己释放这个分配的内存块。

要了解有关 ARC 工作原理的更多信息,请查看 Apple 的 WWDC 2011 会议视频:介绍自动引用计数

基本上,我不明白为什么会导致这个问题?

很难说,但问题可能m_head是只有在m_head == size && overflow == FALSE. 此条件仅在第一次m_head等于时为真,(因为溢出 == FALSE),但在下一次等于m_size时不再为真,因为等于(并且不会重置为 0)。m_headm_sizeoverflowTRUEm_head

于 2012-10-15T21:58:37.760 回答
1

达到 if-condition 为 TRUE 后,溢出设置为 TRUE。但是,这个程序永远不会将溢出重置为 FALSE。所以,m_head 是继续增长的。永远不要重置为零。结果,缓冲区[m_head] 访问超出保留内存。

好?

于 2012-10-15T21:46:05.190 回答