-1
-(BOOL)createTimer
{
    stRs232Timer*   pEvent = malloc(sizeof(stRs232Timer));

    pEvent->bPersistent = YES;                              // setup timer structure
    pEvent->wAppTimerId = 95;
    pEvent->uPeriod     = 50;
    pEvent->bStopped    = NO;
    pEvent->uExpirationTime = 10;

    NSLog(@"bPersistent:%d",pEvent->bPersistent);
    NSLog(@"wAppTimerId:%d",pEvent->wAppTimerId);
    NSLog(@"uPeriod:%d",pEvent->uPeriod);
    NSLog(@"bStopped:%d",pEvent->bStopped);


    NSData* myData = [NSData dataWithBytes:(stRs232Timer*)pEvent length:sizeof(stRs232Timer*)];

    wTimerId = 99;
    pEvent->uPeriod = 51;
    myData = [NSData dataWithBytes:(stRs232Timer*)pEvent length:sizeof(stRs232Timer*)];
         [m_cAppIdMap setObject:myData forKey:[NSNumber numberWithUnsignedShort:wTimerId]];
    wTimerId = 96;
    pEvent->uPeriod = 52;
    myData = [NSData dataWithBytes:(stRs232Timer*)pEvent length:sizeof(stRs232Timer*)];
    [m_cAppIdMap setObject:myData forKey:[NSNumber numberWithUnsignedShort:wTimerId]];
    wTimerId = 97;
    pEvent->uPeriod = 53;
    myData = [NSData dataWithBytes:(stRs232Timer*)pEvent length:sizeof(stRs232Timer*)];
    [m_cAppIdMap setObject:myData forKey:[NSNumber numberWithUnsignedShort:wTimerId]];
    wTimerId = 98;
    pEvent->uPeriod = 54;
    myData = [NSData dataWithBytes:(stRs232Timer*)pEvent length:sizeof(stRs232Timer*)];
    [m_cAppIdMap setObject:myData forKey:[NSNumber numberWithUnsignedShort:wTimerId]];
    wTimerId = 95;
    pEvent->uPeriod = 55;
    myData = [NSData dataWithBytes:(stRs232Timer*)pEvent length:sizeof(stRs232Timer*)];
    [m_cAppIdMap setObject:myData forKey:[NSNumber numberWithUnsignedShort:wTimerId]];

    NSLog(@"The dictionary count now is:%d",[m_cAppIdMap count]);
    NSLog(@"The dictionary values now is:");
    NSLog(@"%@",m_cAppIdMap);

    [m_cPendingEventList addObject:myData];
    NSLog(@"EventList:%@",m_cPendingEventList);

    [self ChangeTimer:95 withPeriod:10];

    free(pEvent);
    return YES;
}

-(BOOL)ChangeTimer:(unsigned short)wTimerIds withPeriod:(uint8_t)uPeriod
{
 stRs232Timer*   pEvent;
    NSLog(@"Into the changeTimer");
    pEvent = (stRs232Timer*)[m_cAppIdMap objectForKey:[NSNumber numberWithUnsignedShort:wTimerIds]];
    NSLog(@"The val is:%@",pEvent);
    if(pEvent!=nil){
        pEvent->bStopped = NO;
        pEvent->uPeriod = uPeriod;
        NSLog(@"completed");
        }       

    return YES;
}

main.m
----------
int main (int argc, const char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSArray1* arr = [[NSArray1 alloc]init];
    [arr createTimer];
    [pool drain];
    return 0;
}

I am getting EXC_BAD_ACCESs runtime exception.Why is it so.I am not accessing any released memory.

EDITED:

2011-05-30 11:21:45.191 NSArray[1091:a0f] bPersistent:1
2011-05-30 11:21:45.194 NSArray[1091:a0f] wAppTimerId:95
2011-05-30 11:21:45.195 NSArray[1091:a0f] uPeriod:50
2011-05-30 11:21:45.195 NSArray[1091:a0f] bStopped:0
2011-05-30 11:21:45.196 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x100110180 of class NSConcreteData autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.196 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x1001102f0 of class NSConcreteData autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.197 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x100110410 of class NSCFNumber autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.197 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x100110a70 of class NSConcreteData autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.198 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x100110ab0 of class NSCFNumber autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.198 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x100110ad0 of class NSConcreteData autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.199 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x100110b10 of class NSCFNumber autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.199 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x100110b30 of class NSConcreteData autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.200 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x100110b70 of class NSCFNumber autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.201 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x1001109e0 of class NSConcreteData autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.201 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x1001105d0 of class NSCFNumber autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.202 NSArray[1091:a0f] The dictionary count now is:5
2011-05-30 11:21:45.202 NSArray[1091:a0f] The dictionary values now is:
2011-05-30 11:21:45.203 NSArray[1091:a0f] {
    98 = <5f000136 000a0000>;
    97 = <5f000135 000a0000>;
    96 = <5f000134 000a0000>;
    99 = <5f000133 000a0000>;
    95 = <5f000137 000a0000>;
}
2011-05-30 11:21:45.203 NSArray[1091:a0f] EventList:(
    <5f000137 000a0000>
)
2011-05-30 11:21:45.204 NSArray[1091:a0f] Into the changeTimer
2011-05-30 11:21:45.204 NSArray[1091:a0f] *** __NSAutoreleaseNoPool(): Object 0x100111130 of class NSCFNumber autoreleased with no pool in place - just leaking
2011-05-30 11:21:45.205 NSArray[1091:a0f] The val is:<5f000137 000a0000>
2011-05-30 11:21:45.205 NSArray[1091:a0f] completed

This is the output i'm getting when removed the NSAutoreleasePool and [pool drain].

If i'm not removing both of this i'm getting EXC_BAD_ACCESS as the run time exception.When i debugged i got exception(EXC_BAD_ACCESS) coming when it comes to [pool drain]; statement.

I could not find out why this happens.

spandana
  • 755
  • 1
  • 13
  • 29

1 Answers1

2

look at this line (and similar):

NSData* myData = [NSData dataWithBytes:(stRs232Timer*)pEvent length:sizeof(stRs232Timer*)];

the amount of bytes is equal to the size of a pointer to stRs232Timer data, which for exmaple for a 32-bit system would be 4 bytes, for 64-bit system 8 bytes - but not the size of stRs232Timer structure. So you are copying not enough bytes.

The cast is also not necessary, so it should be like that:

NSData* myData = [NSData dataWithBytes: pEvent length: sizeof(stRs232Timer)];

BTW this very first instance will be overwritten before it gets saved into the dictionary.

LATER

In ChangeTimer you should use NSData bytes method instead of casting directly to stRs232Timer:

pEvent = (stRs232Timer*)[[m_cAppIdMap objectForKey:[NSNumber numberWithUnsignedShort:wTimerIds]] bytes];

This will give you the pointer to the data, casting NSData directly to stRs232Timer is wrong.

Tomasz Stanczak
  • 12,796
  • 1
  • 30
  • 32
  • @Tomasz:Thanks for pointing out that.I now understand the dangerous thing what i'm doing in my code.But i am still getting the EXC_BAD_ACCESS runtime exception.I dont know where i'm doing the wrong thing. – spandana May 27 '11 at 14:18
  • at what place exactly does it crash? – Tomasz Stanczak May 27 '11 at 17:40
  • First: did you change the code to copy the proper amount of bytes to NSData? The code still copies pointer size buffer. You should also remove the first NSData dataWithBytes call since it is just wast of CPU, as I said it gets overwritten almost immediately. Now I have found another but in ChangeTimer, look into updated answer: cast of NSData to stRs232Timer*: they are different animals, you should cast NSData bytes instead. And as someone suggested: in case of EXC_BAD_ACCESS run Instruments with NSZombie, it has helped me a few times to find out overreleased objects. – Tomasz Stanczak May 30 '11 at 09:41
  • @Tomasz:Thanks .But i could pick the NSZombie instruments.There is an option called record on the corner.I will press that.under allocation there are so many things and there the memory usage will be given.How will i detect the EXC_BAD_ACCESS errors using Zombies. – spandana May 30 '11 at 11:45
  • 98 = <5f000136 000a0000>; 97 = <5f000135 000a0000>; 96 = <5f000134 000a0000>; 99 = <5f000133 000a0000>; 95 = <5f000137 000a0000>; why is that in the second column is same in all the value pairs. – spandana May 30 '11 at 11:46
  • @Tomasz:pEvent = (stRs232Timer*)[[m_cAppIdMap objectForKey:[NSNumber numberWithUnsignedShort:wTimerIds]]bytes];I did the changes as you told me to do.But i got a break in the output at the point of typecasting it into (stRs232Timer*).I'm getting EXC_BAD_ACCESS once again.Sorry i am troubling you again and again.You gave me so many information information that i dont know from your answer. – spandana May 30 '11 at 11:54
  • 1
    Regarding Instruments: I'm afraid it is too complex to explain here, so just in short: if you start Instruments you should be able to select Zombies, then in the Instruments running it will just go on and display a small popup if it finds out a zombie, there you are able to show the stacktrace leading to accessing an overreleased object. – Tomasz Stanczak May 30 '11 at 13:05
  • 1
    But Zombies only help with overreleased objects, if you have a pointer gone wrong it won't. So it may not be a solution now. Are you already registered with apple developer connection? If yes, I would strongly suggest you to look for their podcasts on the apple developer site. They have great video about using Instruments for Zombies, debugging memory problems etc. It has helped me tremendously in understanding how to use it. It is all free after registering, you just have to download it using iTunes. – Tomasz Stanczak May 30 '11 at 13:07
  • And now in this special case I suppose your pointers are still pointing to wrong things, so perhaps you should throw the code away and write it again this time paying very very close attention to pointer type, memory content it points to and memory size that gets copied into NSData. Try to log the contents of NSData bytes directly after creating it and putting into NSDictionary and after getting it back in ChangeTimer, compare what you get - is it the same thing you had put there? – Tomasz Stanczak May 30 '11 at 13:10
  • @Tomasz:It works when we set only one object for NSData.The problem might be due to the overwriting of the myData(NSData object) continuously. I have changed it into NSMutableData and tried as NSData wont be modified.Even with that i got errors.If used a single object to get stored onto the NSData everything works fine.. – spandana May 31 '11 at 10:04