I'm going through an exercise in a mac programming in cocoa book, where there is a GUI and from a textfield I enter and to a list of strings displayed on a table. There are plenty of things that aren't working, the most confusing of which is I keep leaking data. First with NSMutableArray, so I decide to try a c style linked list for whatever reason. I got a prototype to work in C, apply it to my project, it leaks and seg faults whenever I try to to simply print out the string:
struct declaration in header:
struct que {
NSString *sentence;
struct que *next; };
typedef struct que que;
@interface linkedlist : NSObject
{
que *top;
int count;
}
-(void)print_list
{
if(top==nil) {printf("In print_list, top lost its node!\n");exit(3);}
for(que *a=top;a!=0;a=a->next) NSLog(@"\n%@\n",a->next);
}
I even published/archived the app to be standalone and ran it with valgrind and it didn't detect any data loss until I pressed "Check List" button which calls print_list.
entire linkedlist.m:
#import <stdlib.h>
#import <stdio.h>
#import "linkedlist.h"
@implementation linkedlist
-(id)init
{
[super init];
count = 0;
top = 0;
return self;
}
-(void)dealloc
{
[self destroy];
}
+(que *)get_new:(NSString *)str
{
que *nnew = 0;
if(!(nnew = malloc(sizeof(que)))) {printf("In get_new, malloc failed\n"); exit(1);}
nnew->sentence=str;
nnew->next=0;
if (nnew!=nil) printf("Good here\n");
return nnew;
}
+(void)pop:(que**)p
{
if(p!=0)
{
if((*p)!=0)
{
if((*p)->next==0)
{
printf("In pop, popping single node\n");
}
que *a = *p;
(*p)=(*p)->next;
a->next=0;
free(a);
}
else
{
NSLog(@"In pop: Pop passed a null pointer. going to crash\n");
que *a;
a->next=0; //crash
}
}
}
+(void)pop_in_middle:(que**)n
{
if(n!=0)
{
if((*n)!=0)
{
if(!(*n)->next)
{
printf("In pop_in_middle, que->next not set, not popping\n");
}
else
{
if(!(*n)->next->next)
{
printf("In pop_in_middle, que->next->next not set\n");
}
que *h1 = (*n)->next;
que *h2 = (*n)->next->next;
(*n)->next=h2;
h1->next=0;
free(h1);
}
}
}
}
+(void)pop_last:(que**)a
{
que *h = (*a)->next;
(*a)->next=0;
if(h->next)
{
NSLog(@"in pop_last, h->next is either dangling or points to valid memory. About to leak\n");
h->next=0;
}
free(h);
}
+(void)pushed:(que**)a pusher:(que*)b
{
b->next=(*a);
(*a)=b;
}
+(void)add_to_middle:(que**)a str:(NSString *)s
{
que *nnew = [linkedlist get_new:s];
que *holder = (*a)->next;
nnew->next=holder;
(*a)->next=nnew;
}
-(void)dropAt:(int) i
{
count = [self check_count];
if(top!=0)
{
if((!i)||(count==1))
{
NSLog(@"Popping top node\n");
[linkedlist pop:&top];
}
else if(i>=count)
{
NSLog(@"popping last node\n");
que *a;
for(a=top;a->next!=0;a=a->next);
[linkedlist pop_last:&a];
}
else if(count>=2)
{
NSLog(@"popping somewhere in the middle\n");
que *a = top;
for(int x=0;x<(i-1);x++) a=a->next;
[linkedlist pop_in_middle:&a];
}
else
{
NSLog(@"in dropAt, something is wrong with the logic\n");
}
count--;
}
else
{
NSLog(@"In dropAt: Top is 0\n");
}
}
-(void)place:(NSString*)str At:(int)i
{
count = [self check_count];
if(top==0)
{
NSLog(@"Top is initially null\n");
top = [linkedlist get_new:str];
if(top!=nil) printf("Good here apparently. Dereference:\n");
NSLog(@"\n%@\n",top->sentence);
}
else
{
que *nnew = 0;
que *a;
if(i<=0)
{
NSLog(@"Inserting que at top\n");
nnew = [linkedlist get_new:str];
[linkedlist pushed:&top pusher:nnew];
}
else if(i>=count)
{
NSLog(@"Inserting que at bottom\n");
nnew = [linkedlist get_new:str];
for(a=top;a->next!=0;a=a->next);
a->next=nnew;
}
else
{
NSLog(@"Inserting que in middle somewhere\n");
a=top;
for(int x=0;x<(i-1);x++) a=a->next;
[linkedlist add_to_middle:&a str:str];
}
}
count++;
}
-(void)print_list
{
if(top==nil) {printf("In print_list, top lost its node!\n");exit(3);}
for(que *a=top;a!=0;a=a->next) NSLog(@"\n%@\n",a->next);
}
-(int)check_count
{
int i=0;
for(que *a=top;a!=0;a=a->next) i++;
return i;
}
-(int)count
{
return count;
}
-(void)destroy
{
NSLog(@"Linked list about to be destroyed\n");
while(top!=0)
{
[linkedlist pop:&top];
}
}
-(NSString *)stringAt:(int)i
{
NSString *b = @"";
if(i<count)
{
que *a=top;
for(int z=0;((z<i)&&(a->next!=0));z++) a=a->next;
b=a->sentence;
}
return b;
}
@end
so yeah.