Something strange is going on in my code. Basically im doing the network stream application that transfers some data into ring buffer memory on iOS and then afterwards read the memory.
I was getting EXC_BAD_ACCESS
after some undetermined amount of data. So i enabled NSZombieEnabled
and NSAutoreleaseFreedObjectCheckEnabled
and setted the malloc_error_break
and was able to pinpoint the cause of error.
My MainClass
have the property (also tried with strong reference, same behaviour)
@property (nonatomic, retain) RingBuffer *readBuffer;
in the RingBuffer
class im initialising the buffer size as:
-(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;
}
after, i use the push method to insert data in 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;
}
If i remove the push call, application will not crash. If the push call is called it will crash after some time. Sometimes i get 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
... Sometimes it is just EXC_BAD_ACCESS.
Basically, what i don't understand is why is this causing the issue ? Is it possible that ARC released the calloced memory ?
Is it possible that ARC released the calloced memory ?
No, that is not possible. ARC, which is an abbreviation for Automatic Reference Counting, is a compiler feature that, if enabled, provides automatic memory management of Objective C objects, by inserting release, retain and autorelease memory calls directly into your compiled code. Since buffer
is not an Objective C object, but a pointer to an allocated block of memory on the heap, which is not released by ARC. It is your obligation to free this allocated block of memory yourself.
To learn more about how ARC works, checkout Apple's WWDC 2011 session video: Introducing Automatic Reference Counting.
Basically, what i don't understand is why is this causing the issue ?
Hard to say, but the issue could be that m_head
is only set to zero if m_head == size && overflow == FALSE
. This condition is ONLY true the first time m_head
equals m_size
, (because overflow == FALSE), but will no longer be true the next time m_head
equals m_size
, because overflow
equals TRUE
(and m_head
will not be reset to 0).