我的代码中发生了一些奇怪的事情。基本上我正在做网络流应用程序,将一些数据传输到iOS上的环形缓冲区内存,然后读取内存。
经过一些不确定的数据后,我得到了EXC_BAD_ACCESS
。所以我启用了NSZombieEnabled
和NSAutoreleaseFreedObjectCheckEnabled
并设置了malloc_error_break
,并且能够查明错误原因。
我的MainClass
拥有该属性(也尝试使用强引用,同样的行为)
@property(nonatomic,retain)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;
}
如果我删除了推送呼叫,应用程序将不会崩溃。如果调用了push调用,它将在一段时间后崩溃。有时我得到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是否有可能释放出calloced内存?
答案 0 :(得分:2)
ARC是否有可能释放出calloced内存?
不,那是不可能的。 ARC是自动引用计数的缩写,是一种编译器功能,如果启用,它通过将释放,保留和自动释放内存调用直接插入到已编译的代码中,提供Objective C对象的自动内存管理。由于buffer
不是Objective C对象,而是指向堆上未分配的内存块的指针,而ARC未释放。您有义务自己释放这个分配的内存块。
要详细了解ARC的工作原理,请查看Apple的WWDC 2011会话视频:Introducing Automatic Reference Counting。
基本上,我不明白为什么会导致这个问题?
很难说,但问题可能是m_head
仅在m_head == size && overflow == FALSE
时设置为零。这条件仅在第一次m_head
等于m_size
时才会出现,(因为溢出== FALSE),但下次m_head
等于m_size
时将不再为真,因为overflow
等于TRUE
(并且m_head
不会重置为0)。
答案 1 :(得分:1)
到达if-condition为TRUE后,溢出设置为TRUE。 但是,这个程序永远不会将溢出重置为FALSE。 所以,m_head继续增长很多。 永远不要重置为ZERO。 结果,缓冲区[m_head]访问保留的内存。
OK?