Amazon.com Widgets Exercise 19.4 - Segmentation Fault 11?
Welcome, Guest. Please login or register.
Did you miss your activation email?
June 20, 2013, 05:05:34 AM
Home Help Search chat Login Register   
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+  Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+  Old Stuff
| |-+  Chapter Study
| | |-+  Chapter 19 - Archiving
| | | |-+  Exercise 19.4 - Segmentation Fault 11?
Pages: [1]   Go Down
Print
Author Topic: Exercise 19.4 - Segmentation Fault 11?  (Read 837 times)
applefan90
Newbie
*
Posts: 29






« on: May 31, 2012, 11:47:55 PM »

I got this exercise to work, with one small issue.

./lookup TEXT_TO_SEARCH

After giving the search information, it prints "Segmentation fault: 11" and I cannot figure out why.  If someone could look over this code and assist me in figuring it out, it would be greatly appreciated.

Thanks in advance!

NOTE: There are two calls to main(); one is commented out while the other actually runs upon the ./lookup command.  The reason for this is the first main() set up the archive.  Long story short, I didn't feel like making another Xcode project.

AddressCard.h
Code: (Objective-C)
#import <Foundation/Foundation.h>

@interface AddressCard : NSObject <NSCoding>
{
    NSString *name;
    NSString *surname;
    NSString *fullName;
    NSString *email;
    NSString *streetAddress;
    NSString *city;
    NSString *state;
    NSString *country;
    NSString *phoneNumber;
    NSString *zip;
    NSString *nextField;
    NSMutableArray *fields; // An array of every field in each card.
    BOOL isFound; // Is the match found?
}
@property (copy, nonatomic) NSString *name, *surname, *fullName, *email, *streetAddress, *city, *state, *country, *phoneNumber, *nextField, *zip;
@property (copy, nonatomic) NSMutableArray *fields;
@property BOOL isFound;

-(void) setName: (NSString*) theName andSurname: (NSString*) theSurname;
-(void) print;
-(NSComparisonResult) compareNames: (id) element;
-(void) addFieldsToCard;
-(void) searchAll: (NSString*) theSearch;

@end

AddressCard.m
Code: (Objective-C)
#import "AddressCard.h"

@implementation AddressCard

@synthesize name, surname, fullName, email, streetAddress, city, state, country, phoneNumber, nextField, zip;
@synthesize fields;
@synthesize isFound;

-(void) setName: (NSString*) theName andSurname: (NSString*) theSurname {
    //    self.name = theName;
    //    self.email = theEmail;
    //    Same thing!
    [self setName: theName];
    [self setSurname: theSurname];
}

-(void) print {
    NSLog (@"====================================");
    NSLog (@"|                                  |");
    NSLog (@"| %10s %-21s |", [name UTF8String], [surname UTF8String]);
    NSLog (@"|----------------------------------|");
    NSLog (@"|                                  |");
    NSLog (@"| %-32s |", [email UTF8String]);
    NSLog (@"| %-32s |", [streetAddress UTF8String]);
    NSLog (@"| %-10s, %-2s %-17s |",[city UTF8String],[state UTF8String],[zip UTF8String]);
    NSLog (@"| %-32s |", [country UTF8String]);
    NSLog (@"| %-32s |", [phoneNumber UTF8String]);
    NSLog (@"|                                  |");
    NSLog (@"|                                  |");
    NSLog (@"|          O           O           |");
    NSLog (@"====================================");
}

-(void) dealloc
{
    [name release];
    [surname release];
    [email release];
    [streetAddress release];
    [city release];
    [state release];
    [zip release];
    [country release];
    [phoneNumber release];
    [fields release];
    [super dealloc];
}

-(NSComparisonResult) compareNames:(id)element
{
    return [name compare: [element surname]];
}

-(void) addFieldsToCard
{
    [fields autorelease];
    
    fields = [[NSMutableArray alloc] initWithCapacity: 0];
    
    [fields addObject: [self name]];
    [fields addObject: [self surname]];
    [fields addObject: [self fullName]];
    [fields addObject: [self email]];
    [fields addObject: [self streetAddress]];
    [fields addObject: [self city]];
    [fields addObject: [self state]];
    [fields addObject: [self country]];
    [fields addObject: [self phoneNumber]];
    [fields addObject: [self zip]];
}

-(void) searchAll: (NSString*) theSearch
{  
    int numFields = [fields count];
    
    NSRange match;
    isFound = FALSE;
    BOOL isDoneSearching = FALSE;
    
    NSLog(@"\n");
    NSLog(@"Lookup: %@",theSearch);
    for ( int i = 0 ; i < numFields ; ++i ) {
        if ( !(isFound) ) { // If it's NOT been found yet            
            nextField = [fields objectAtIndex: i];
            match = [nextField rangeOfString: theSearch options:NSCaseInsensitiveSearch];
            if(match.location != NSNotFound) {
                NSLog(@"Match found in %@'s card.",[self fullName]);
                isFound = TRUE;
                isDoneSearching = TRUE;
            }
        }
    }
    if( (!(isFound)) )
        NSLog(@"No match found in %@'s card.",[self fullName]);
}

-(void) encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject: name forKey:          @"AddressCardName"];
    [encoder encodeObject: surname forKey:       @"AddressCardSurname"];
    [encoder encodeObject: fullName forKey:      @"AddressCardFullName"];
    [encoder encodeObject: email forKey:         @"AddressCardEmail"];
    [encoder encodeObject: streetAddress forKey: @"AddressCardStreetAddress"];
    [encoder encodeObject: city forKey:          @"AddressCardCity"];
    [encoder encodeObject: state forKey:         @"AddressCardState"];
    [encoder encodeObject: country forKey:       @"AddressCardCountry"];
    [encoder encodeObject: phoneNumber forKey:   @"AddressCardPhoneNumber"];
    [encoder encodeObject: zip forKey:           @"AddressCardZip"];
//    [encoder encodeObject: nextField forKey:     @"AddressCardNextField"];
    [encoder encodeObject: fields forKey:        @"AddressCardFields"];
//    [encoder encodeBool:   isFound forKey:       @"AddressCardIsFound"];
    NSLog(@"Card archived.");
}

-(id) initWithCoder:(NSCoder *)decoder
{
    name          = [[decoder decodeObjectForKey: @"AddressCardName"] retain];
    surname       = [[decoder decodeObjectForKey: @"AddressCardSurname"] retain];
    fullName      = [[decoder decodeObjectForKey: @"AddressCardFullName"] retain];
    email         = [[decoder decodeObjectForKey: @"AddressCardEmail"] retain];
    streetAddress = [[decoder decodeObjectForKey: @"AddressCardStreetAddress"] retain];
    city          = [[decoder decodeObjectForKey: @"AddressCardCity"] retain];
    state         = [[decoder decodeObjectForKey: @"AddressCardState"] retain];
    country       = [[decoder decodeObjectForKey: @"AddressCardCountry"] retain];
    phoneNumber   = [[decoder decodeObjectForKey: @"AddressCardPhoneNumber"] retain];
    zip           = [[decoder decodeObjectForKey: @"AddressCardZip"] retain];
//    nextField     = [[decoder decodeObjectForKey: @"AddressCardNextField"] retain];
    fields        = [[decoder decodeObjectForKey: @"AddressCardFields"] retain];
//    isFound       =  [decoder decodeBoolForKey:   @"AddressCardIsFound"];
    NSLog(@"Card unarchived.");
    
    return self;
}

@end

AddressBook.h
Code: (Objective-C)
#import "AddressCard.h"

@interface AddressBook: NSObject <NSMutableCopying, NSCoding>
{
    NSString *bookName;
    NSMutableArray *book;
    AddressCard *nextCard;
    BOOL isSorted;
    NSMutableArray *matches;  // An array of every match found in a search.
}

@property (copy, nonatomic) NSString *bookName;
@property BOOL isSorted;

-(id) initWithName: (NSString *) name;
-(void) addCard: (AddressCard *) theCard;
-(void) removeCard: (AddressCard *) theCard;
-(void) removeAllCards;
-(int) entries;
-(void) list;
-(void) dealloc;
-(void) lookup: (NSString*) theSearch;
-(void) printMatches: (NSString*) match;
-(void) sort;

@end

AddressBook.m
Code: (Objective-C)
#import "AddressBook.h"

@implementation AddressBook

@synthesize bookName;
@synthesize isSorted;

-(void) encodeWithCoder:(NSCoder *)encoder
{
    [encoder encodeObject: bookName forKey: @"AddressBookBookName"];
    [encoder encodeObject: book forKey:     @"AddressBookBook"];
//    [encoder encodeObject: nextCard forKey: @"AddressBookNextCard"];
//    [encoder encodeObject: matches forKey:  @"AddressBookMatches"];
//    [encoder encodeBool:   isSorted forKey: @"AddressBookIsSorted"];
    NSLog(@"Book archived.");
}

-(id) initWithCoder:(NSCoder *)decoder
{
    bookName = [[decoder decodeObjectForKey: @"AddressBookBookName"] retain];
    book     = [[decoder decodeObjectForKey: @"AddressBookBook"] retain];
//    nextCard = [[decoder decodeObjectForKey: @"AddressBookNextCard"] retain];
//    matches  = [[decoder decodeObjectForKey: @"AddressBookMatches"] retain];
//    isSorted =  [decoder decodeBoolForKey:   @"AddressBookIsSorted"];
    NSLog(@"Book unarchived.");
    
    return self;
}

-(id) mutableCopyWithZone:(NSZone *)zone
{
    AddressBook *newBook = [[[self class] allocWithZone: zone] initWithName: [self bookName]];
    newBook->book = [self->book mutableCopy];
    return newBook;
}

-(id) initWithName:(NSString *)name
{
    isSorted = FALSE;
    self = [super init];
    
    if ( self )
    {
        bookName = [[NSString alloc] initWithString: name];
        book = [[NSMutableArray alloc] init];
    }
    
    return self;
    
}

-(void) addCard:(AddressCard *)theCard
{
    [book addObject: theCard];
}

-(void) removeCard:(AddressCard *)theCard
{
    [book removeObjectIdenticalTo: theCard];
}

-(int) entries
{
    return [book count];
}

-(void) list
{
    NSLog(@"============== Contents of %-@: ==============",bookName);
    NSLog(@"First name:  Last name:      Email:");
    NSLog(@"-----------  ----------      ------");
    for ( nextCard in book )
        NSLog(@"%-12s %-15s %-25s",[nextCard.name UTF8String],[nextCard.surname UTF8String],[nextCard.email UTF8String]);
    
    NSLog(@"========================================================");
}

-(void) dealloc
{
    [bookName release];
    [book release];
    [nextCard release];
    [matches release];
    [super dealloc];
}

-(void) lookup:(NSString *)theSearch
{
    if ( [book count] == 0 ) {
        NSLog(@"Cannot search an empty book.  Add cards, then try searching again.");
        return;
    }
    if( !(matches) )
        matches = [[NSMutableArray alloc] initWithCapacity: 20];
    int numCardsSearched = 0;
    [nextCard release];
    for ( nextCard in book ) {
        [nextCard searchAll: theSearch];
        ++numCardsSearched;
        if( [nextCard isFound] )
            [matches addObject: nextCard];
        if ( numCardsSearched == [book count] )
            if ([matches count] > 0)
                [self printMatches: theSearch];
            else {
                NSLog(@"\n");
                NSLog(@"No matches found for %@ in %@.",theSearch,[self bookName]);
            }
    }
}

-(void) printMatches: (NSString*) match
{
    NSLog(@"\n");
    NSLog(@"Matches found for: \"%@\"", match);
    
    for ( AddressCard *theMatch in matches )
        [theMatch print];
    
}


-(void) sort  // Sorts the cards in the book by last name.
{
    if( [self isSorted] == FALSE ) {
        NSLog(@"\n");
        NSLog(@"Sorting...");
        [book sortUsingSelector: @selector(compareNames:)];
        [self setIsSorted: TRUE];
        NSLog(@"Sorted!");
        NSLog(@"\n");
    }
    else {
        NSLog(@"Already sorted, dumbass!");
        NSLog(@"\n");
    }
    
}

-(void) removeAllCards
{
    [book removeAllObjects];
}

@end

main.m
Code: (Objective-C)
#import "AddressBook.h"

/***** This program sets up the archive-retrieval program. *****
int main(int argc, const char * argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    AddressCard *card1  = [[AddressCard alloc] init];
    AddressCard *card2  = [[AddressCard alloc] init];
    
    AddressBook *myBook = [[AddressBook alloc] initWithName: @"Justin's book"];
    
//    NSMutableData *data;
//    NSKeyedArchiver *archiver = [NSKeyedUnarchiver
    
    NSString *aName = @"NameA";
    NSString *bName = @"NameB";
    NSString *aSurname = @"SurnameA";
    NSString *bSurname = @"SurnameB";
    NSString *aFullName = [aName stringByAppendingString: @" "];
    NSString *bFullName = [bName stringByAppendingString: @" "];
    aFullName = [aFullName stringByAppendingString: aSurname];
    bFullName = [bFullName stringByAppendingString: bSurname];
    NSString *aEmail = @"someone@somewhere.com";
    NSString *bEmail = @"someoneelse@somewhere.com";
    NSString *aStreetAddress = @"123 Some St.";
    NSString *bStreetAddress = @"321 Someother St.";
    NSString *aCity = @"Anytown";
    NSString *bCity = @"Anycity";
    NSString *aState = @"STATE1";
    NSString *bState = @"STATE2";
    NSString *aZip = @"12345";
    NSString *bZip = @"54321";
    NSString *aCountry = @"USA";
    NSString *bCountry = @"USA";
    NSString *aPhoneNumber = @"555-555-5555;
    NSString *bPhoneNumber = @"555-555-5556";
    
    [card1 setName: aName];
    [card1 setSurname: aSurname];
    [card1 setFullName: aFullName];
    [card1 setEmail: aEmail];
    [card1 setStreetAddress: aStreetAddress];
    [card1 setCity: aCity];
    [card1 setState: aState];
    [card1 setZip: aZip];
    [card1 setCountry: aCountry];
    [card1 setPhoneNumber: aPhoneNumber];
    
    [card2 setName: bName];
    [card2 setSurname: bSurname];
    [card2 setFullName: bFullName];
    [card2 setEmail: bEmail];
    [card2 setStreetAddress: bStreetAddress];
    [card2 setCity: bCity];
    [card2 setState: bState];
    [card2 setZip: bZip];
    [card2 setCountry: bCountry];
    [card2 setPhoneNumber: bPhoneNumber];
    
    [card1 addFieldsToCard];
    [card2 addFieldsToCard];
    
    [myBook addCard:card1];
    [myBook addCard:card2];
    
//    data = [NSMutableData data];
//    archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData: data];
    
    
//    [archiver encodeObject: card1 forKey: @"Card1"];
//    [archiver encodeObject: card2 forKey: @"Card2"];
//    [archiver encodeObject: myBook forKey: @"myBook"];
//    [archiver finishEncoding];
    
//    if ( [data writeToFile: @"backup.archive" atomically: YES] == NO )
//        NSLog(@"Backup failed.");
//    else NSLog(@"Backup successful!");
    
    if ( [NSKeyedArchiver archiveRootObject: myBook toFile: @"backup.archive"] == NO ) {
        NSLog(@"Backup failed.");
        return 1;
    }
    else NSLog(@"Backup successful.");
    
    NSLog(@"%@",[[NSFileManager defaultManager] currentDirectoryPath]);
    
//    [archiver release];
    
    [card1 release];
    [card2 release];
    
    [myBook release];
    
    [pool drain];
    
    return 0;
}
 *****  *****/

/*
 *  4. Write a program to read in an archived
 *  AddressBook and look up an entry based on a
 *  name supplied on the command line, like so:
 *  $ lookup gregory
 */

// This is what actually runs.

int main(int argc, const char *argv[])
{
    NSAutoreleasePool *pool   = [[NSAutoreleasePool alloc] init];
    NSProcessInfo     *proc   = [NSProcessInfo processInfo];
    NSArray           *args   = [proc arguments];
//    NSMutableData     *data;
//    NSKeyedUnarchiver *unarchiver;
    AddressBook       *myBook;
//    AddressCard       *card1;
//    AddressCard       *card2;
    
    if ( [args count] != 2 ) {
        NSLog(@"Usage: ./%@ SEARCH",[proc processName]);
        return 1;
    }
    
//    data = [NSMutableData dataWithContentsOfFile: @"backup.archive"];
    
//    if (!data)
//    {
//        NSLog(@"File read failed.");
//        return 2;
//    }
//    else NSLog(@"File read successful.");
    
//    unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData: data];
    
//    card1 = [unarchiver decodeObjectForKey: @"Card1"];
//    card2 = [unarchiver decodeObjectForKey: @"Card2"];
//    myBook = [unarchiver decodeObjectForKey: @"myBook"];
//    [unarchiver finishDecoding];
    
    myBook = [NSKeyedUnarchiver unarchiveObjectWithFile: @"backup.archive"];
    
    if( !myBook ) {
        NSLog(@"File read failed.");
        return 2;
    }
    else NSLog(@"File read successful.");
    
    [myBook list];
    
    [myBook lookup: [args objectAtIndex: 1]];
    
    [myBook release];
    
//    [unarchiver release];
    
    [pool drain];
    return 0;
}
« Last Edit: June 01, 2012, 08:45:06 PM by applefan90 » Logged
applefan90
Newbie
*
Posts: 29






« Reply #1 on: June 01, 2012, 09:03:39 PM »

I figured it out.  I was releasing myBook after unarchiving it; I wasn't aware that it was autoreleased in the unarchiving process.
Logged
Pages: [1]   Go Up
Print
Jump to:  



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.