Advertise here




Advertise here

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID
Please do not post the same thing multiple times. The board software automatically flags certain posts as needing moderator attention. This happens the most often for new users. I'm pretty sure this is made clear at the time you attempt to post. Posting the same thing over and over again just makes that many more posts the moderators have to weed through later. This makes us sad. Don't make us sad. If your post/thread doesn't appear, just wait a while. Don't post it again. If it hasn't shown up by the next day, then you can try again. I normally go through posts in the mornings, and try to check a few times throughout the day, but I'm not here 24/7. There will typically be a significant delay before posts are approved. Just be patient.

Strangest Problem I Have Seen Please Help

MysteryMystery Posts: 16Registered Users
Hello Everyone. This is one the strangest problems I've come across. I can't seem to find an explanation. The application crashes when NSLog("It works!") is commented out and gives an EXC_BAD_ACCESS error. But when I uncomment this line. The application runs as it should.

This method is supposed to obtain car data from an sql file and set the columns as the properties of a singleton. The information is displayed in another view. The line in bold is the one giving me trouble.


-(void) obtainCarData{

//Get the file path of the database to open it
//databaseName = @\"Car Database.sqlite\";
//NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
//NSString *documentsDir = [documentPaths objectAtIndex:0];
//databasePath = [documentsDir stringByAppendingPathComponent:databaseName];

sqlite3 *database;

NSString *userCarType = [NSString stringWithFormat:@\"Compact\"];
NSString *userCarYear = [NSString stringWithFormat:@\"2010\"];

if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {

NSString *sqlStatement = [NSString stringWithFormat:@\"select * from CarDatabase where Type = '%@' and Year = '%@'\",userCarType,userCarYear];

sqlite3_stmt *compiledStatement;

int num = sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL);
if(num == SQLITE_OK) {
[B]NSLog(@\"It Works!\");[/B]
}
//else{
//printf( \"Error LOG: %s\", sqlite3_errmsg(database) );
// NSLog(@\"num:%d\", num);
// }

if (sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) {

while (sqlite3_step(compiledStatement) == SQLITE_ROW) {

[Car userCar].index = [NSNumber numberWithInt:(int)sqlite3_column_int(compiledStatement, 0)];
[Car userCar].carModel = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(compiledStatement, 1)];
[Car userCar].carClass= [NSString stringWithUTF8String:(const char *)sqlite3_column_text(compiledStatement, 2)];
[Car userCar].carYear = [NSNumber numberWithInt:(int)sqlite3_column_int(compiledStatement, 3)];
[Car userCar].wheelRadius= [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 4)];
[Car userCar].differential = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 5)];
[Car userCar].engineSize = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 6)];
[Car userCar].cylinders = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 7)];
[Car userCar].gears = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 8)];
[Car userCar].gearRatio1 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 9)];
[Car userCar].gearRatio2 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 10)];
[Car userCar].gearRatio3 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 11)];
[Car userCar].gearRatio4 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 12)];
[Car userCar].gearRatio5 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 13)];
[Car userCar].gearRatio6 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 14)];
[Car userCar].gearMax1 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 15)];
[Car userCar].gearMax2 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 16)];
[Car userCar].gearMax3 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 17)];
[Car userCar].gearMax4 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 18)];
[Car userCar].gearMax5 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 19)];
[Car userCar].gearMin1 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 20)];
[Car userCar].gearMin2 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 21)];
[Car userCar].gearMin3 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 22)];
[Car userCar].gearMin4 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 23)];
[Car userCar].gearMin51 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 24)];

sqlite3_finalize(compiledStatement);
sqlite3_close(database);
}
}
}
}


Could someone please tell me what is going on? I'm confused as to why it is not letting me remove the NSLog.
Post edited by Mystery on

Replies

  • mavrik5150mavrik5150 Posts: 194Registered Users
    The EXC_BAD_ACCESS error usually means there's a Memory issue and that's why it's crashing. I had this happen once as well with the same setup (once a NSLog statement was removed it crashed) and although I can't really explain why this happens I did fix it by using the Instruments tool (checking for Zombies) and found the object that was being double released in my case and causing the issue. The only thing I could think why the NSLog made a difference is that the memory was being shifted around so it didn't cause a problem at that given moment but I'm pretty sure the app would have still crashed later down the line as that one item was still being double called and taking up a piece of the memory.
  • dljefferydljeffery Posts: 1,311iPhone Dev SDK Supporter, Registered Users
    That seems unlikely.

    What exactly does your code that crashes look like? Can you post it here (instead of general instructions on how to modify the non-crashing code)?

    Also, exactly where does it crash? Have you stepped through it, line by line, in the debugger?

    EDIT: To clarify, my response is to the OP, not in response to mavrik5150's response. Just in case any part of it might have seemed otherwise... :)
    Recall It! Tag your notes. Tag your photos. Tag your thoughts. Tag your life.

    Recall It! for iPad
  • MysteryMystery Posts: 16Registered Users
    mavrik5150;360636 said:
    The EXC_BAD_ACCESS error usually means there's a Memory issue and that's why it's crashing. I had this happen once as well with the same setup (once a NSLog statement was removed it crashed) and although I can't really explain why this happens I did fix it by using the Instruments tool (checking for Zombies) and found the object that was being double released in my case and causing the issue. The only thing I could think why the NSLog made a difference is that the memory was being shifted around so it didn't cause a problem at that given moment but I'm pretty sure the app would have still crashed later down the line as that one item was still being double called and taking up a piece of the memory.
    Thanks for the suggestion! I do realize that the EXC_BAD_ACCESS is a memory issue. I have also used the NSZombie to see if, as you said, i am releasing an object twice. The NSZombie highlighted this line.

    while (sqlite3_step(compiledStatement) == SQLITE_ROW) {

    And I know that NSZombie does not always select the right line but I don't see any sources of error around there. And it is not just the NSLog that is required .

    int num = sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL);
    if(num == SQLITE_OK) {
    NSLog(@"It Works!");
    }

    This whole section is required for some reason. If I leave this out, the program crashes. If i leave it in, the program does run as it is intended to so I am not sure if what you said about the memory shift is true. Although I could be wrong. So I still don't know how to fix this.
  • apatsufasapatsufas Posts: 121Registered Users
    I don't know if this will solve your problem but you are finalizing the SQL statement and you are closing the database connection in the while loop, in which you are reading the results returned from the executed statement. Try changing the code to this:


    if (sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {

    NSString *sqlStatement = [NSString stringWithFormat:@\"select * from CarDatabase where Type = '%@' and Year = '%@'\",userCarType,userCarYear];

    sqlite3_stmt *compiledStatement;

    int num = sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL);
    if(num == SQLITE_OK) {
    NSLog(@\"It Works!\");
    }
    //else{
    //printf( \"Error LOG: %s\", sqlite3_errmsg(database) );
    // NSLog(@\"num:%d\", num);
    // }

    if (sqlite3_prepare_v2(database, [sqlStatement UTF8String], -1, &compiledStatement, NULL) == SQLITE_OK) {

    while (sqlite3_step(compiledStatement) == SQLITE_ROW) {

    [Car userCar].index = [NSNumber numberWithInt:(int)sqlite3_column_int(compiledStatement, 0)];
    [Car userCar].carModel = [NSString stringWithUTF8String:(const char *)sqlite3_column_text(compiledStatement, 1)];
    [Car userCar].carClass= [NSString stringWithUTF8String:(const char *)sqlite3_column_text(compiledStatement, 2)];
    [Car userCar].carYear = [NSNumber numberWithInt:(int)sqlite3_column_int(compiledStatement, 3)];
    [Car userCar].wheelRadius= [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 4)];
    [Car userCar].differential = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 5)];
    [Car userCar].engineSize = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 6)];
    [Car userCar].cylinders = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 7)];
    [Car userCar].gears = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 8)];
    [Car userCar].gearRatio1 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 9)];
    [Car userCar].gearRatio2 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 10)];
    [Car userCar].gearRatio3 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 11)];
    [Car userCar].gearRatio4 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 12)];
    [Car userCar].gearRatio5 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 13)];
    [Car userCar].gearRatio6 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 14)];
    [Car userCar].gearMax1 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 15)];
    [Car userCar].gearMax2 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 16)];
    [Car userCar].gearMax3 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 17)];
    [Car userCar].gearMax4 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 18)];
    [Car userCar].gearMax5 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 19)];
    [Car userCar].gearMin1 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 20)];
    [Car userCar].gearMin2 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 21)];
    [Car userCar].gearMin3 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 22)];
    [Car userCar].gearMin4 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 23)];
    [Car userCar].gearMin51 = [NSNumber numberWithDouble:(double)sqlite3_column_double(compiledStatement, 24)];



    }
    }
    sqlite3_finalize(compiledStatement);
    }
    sqlite3_close(database);
    SQLed - Your Database Manager on the go



    iAZConverter
  • MysteryMystery Posts: 16Registered Users
    dljeffery;360637 said:
    That seems unlikely.

    What exactly does your code that crashes look like? Can you post it here (instead of general instructions on how to modify the non-crashing code)?

    Also, exactly where does it crash? Have you stepped through it, line by line, in the debugger?

    EDIT: To clarify, my response is to the OP, not in response to mavrik5150's response. Just in case any part of it might have seemed otherwise... :)

    The problem was solved. I looked into the while loop as indicated by the NSZombie line by line and realized that the finalize and close statement was in the wrong place. It should have been outside the while loop. I still wonder why it would work with that snippet of code though... But thanks for your help guys.

    @apatsufas: Yes! That is exactly what I did! And it fixed the problem. You found it as soon as I fixed it haha. Thanks.
  • dljefferydljeffery Posts: 1,311iPhone Dev SDK Supporter, Registered Users
    It's probably a side effect of the SQLite implementation.

    In your initial code with the NSLog that worked, you were actually preparing the statement twice (once to log the result, then again to actually use it). Perhaps SQLite maps these both to the same actual statement internally, so that calling finalize too soon on one doesn't actually destroy the underlying compiled statement? (even though you were calling finalize on every row... hmm... how many rows do you actually have? two?)

    Just guessing, based on your observed behavior, though.
    Recall It! Tag your notes. Tag your photos. Tag your thoughts. Tag your life.

    Recall It! for iPad
  • MysteryMystery Posts: 16Registered Users
    dljeffery;360648 said:
    It's probably a side effect of the SQLite implementation.

    In your initial code with the NSLog that worked, you were actually preparing the statement twice (once to log the result, then again to actually use it). Perhaps SQLite maps these both to the same actual statement internally, so that calling finalize too soon on one doesn't actually destroy the underlying compiled statement? (even though you were calling finalize on every row... hmm... how many rows do you actually have? two?)

    Just guessing, based on your observed behavior, though.
    I think I understand what you're trying to explain. I actually have 9 rows. The one in which I told it to search for is on the third row. So although what you proposed is a good estimation, since it's on the third row it may be false.

    I repeated the problem again and I caught a glimpse of the UIView before it closed for a crash (which it did not do before) and it displayed the correct information right before it closed.

    The information I gave in the beginning and now may not be enough information to determine exactly what happened here. It is still a good puzzle nonetheless. At least the problem is solved... Thanks!
Sign In or Register to comment.