Invalid memory reference (SIGSEGV) and incomplete implementation of class error - objective-c

I am writing a small recursive function to calculate the sum of integers from an array. However, I am getting errors and warnings. Anybody help me to solve these issues?
#import <Foundation/Foundation.h>
#interface SumIntegers:NSObject
{
NSInteger result;
}
-(NSInteger)calcutateSum:(NSInteger)value;
-(void) printSum;
#end
#implementation SumIntegers
-(NSInteger)calculateSum:(NSInteger)value
{
NSInteger sum = 0;
//sum = sum + [[self calculateSum:[array objectAtIndex:i]] integerValue];
sum = sum + [self calculateSum:value];
result = sum;
return result;
}
-(void) printSum
{
NSLog(#"Sum of integer list is %i",result);
}
#end
int main (int argc, const char * argv[])
{
NSInteger i;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *intArray = [NSMutableArray arrayWithObjects:[NSNumber numberWithInteger:1],[NSNumber numberWithInt:3],[NSNumber numberWithInt:5]
,[NSNumber numberWithInt:7],[NSNumber numberWithInt:9],nil];
SumIntegers *sumIntegers = [[SumIntegers alloc]init];
for (i = 0; i<[intArray count]; i++)
{
NSInteger hhh = [sumIntegers calculateSum:[[intArray objectAtIndex:i] integerValue]];
}
[sumIntegers printSum];
[pool drain];
return 0;
}
What I did is I created an interface SumIntegers and created a recursive function to calculate the sum of integers. However, somehow this function is not recognized and also getting warning "incomplete implementation of class #end" and memory error.
Warning(s):
source_file.m:31:1: warning: incomplete implementation of class ‘SumIntegers’
#end
^
source_file.m:31:1: warning: method definition for ‘-calcutateSum:’ not found
source_file.m: In function ‘main’:
source_file.m:44:19: warning: unused variable ‘hhh’ [-Wunused-variable]
NSInteger hhh = [sumIntegers calculateSum:[[intArray objectAtIndex:i] integerValue]];
^
Error(s):
Invalid memory reference (SIGSEGV)

Here is my answer to above problem. There is no need of return value or argument in the calculateSum method. Simply adding array value into the sum and then calling the calculateSum method again until num is less than array count.
#import <Foundation/Foundation.h>
#interface SumOfIntegers:NSObject
{
NSMutableArray *intArray;
NSInteger sum;
NSInteger num;
}
#property NSMutableArray *intArray;
#property NSInteger sum, num;
-(void) calculateSum;
#end
#implementation SumOfIntegers
#synthesize intArray, sum, num;
-(void) calculateSum{
if(num < [intArray count])
{
NSLog(#"number is.... %i", num);
sum = sum + [[intArray objectAtIndex:num++] integerValue];
[self calculateSum];
}
else
{
NSLog(#"Sum of integers is %i", sum);
}
}
#end
int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSNumber numberWithInteger:1],[NSNumber numberWithInt:3],[NSNumber numberWithInt:5]
,[NSNumber numberWithInt:7],[NSNumber numberWithInt:9],nil];
SumOfIntegers *sumOfIntegers = [[SumOfIntegers alloc]init];
sumOfIntegers.intArray = array;
sumOfIntegers.sum = 0;
sumOfIntegers.num = 0;
[sumOfIntegers calculateSum];
[pool drain];
return 0;
}

In modern ObjC:
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSArray *nums = #[#(1), #(2), #(3)];
NSLog(#"%#", [nums valueForKeyPath:#"#sum.self"]);
}
return 0;
}

Related

Objective-C method_exchangeImplementations result is not as expected

I'm learning Objective-C runtime, and try to use method_exchangeImplementations to exchange addObject: method and removeObject: method of NSMutableArray.
My code like this:
int main(int argc, const char * argv[]) {
#autoreleasepool {
Method removeMethod = class_getInstanceMethod(NSMutableArray.class, #selector(removeObject:));
Method addMethod = class_getInstanceMethod(NSMutableArray.class, #selector(addObject:));
method_exchangeImplementations(addMethod, removeMethod);
NSMutableArray *array = [[NSMutableArray alloc] init];
NSObject *obj = [[NSObject alloc] init];
[array removeObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 1, actual print 1
[array addObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 0, actual print 2
}
return 0;
}
I expect exchange add/remove function, but seems like only removeObject: has been exchange to addObject: , addObject: still is addObject to array, now I have two addObject method of NSMutableArray
I'm not sure the reason. I try to exchange other method like uppercaseString/lowercaseString of NSString, that work correct.
OK, I solved problem. Thanks #Willeke for the tip.
The real class of my array is not NSMutableArray, so use NSMutableArray.class in class_getInstanceMethod can't get correct method. Use [array class] is the answer.
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSMutableArray *array = [[NSMutableArray alloc] init];
Method removeMethod = class_getInstanceMethod([array class], #selector(removeObject:));
Method addMethod = class_getInstanceMethod([array class], #selector(addObject:));
method_exchangeImplementations(addMethod, removeMethod);
NSObject *obj = [[NSObject alloc] init];
[array removeObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 1, actual print 1
[array addObject:obj];
NSLog(#"%lu", (unsigned long)array.count); // expect print 0, actual print 0
}
return 0;
}

copy and sort an NSArray in one step

I am trying to sort an NSArray.
Unfortunately the array appears to stay empty.
I start with an NSMutableArray with normal distributed data called "gaussianPopulation" which is then to be copied and sorted into the NSArray "sortedData".
I checked a similar post here: Sorting NSArray and returning NSArray?
But I am still missing something...
Population.h:
#define ARC4RANDOM_MAX 0x100000000
#import <Foundation/Foundation.h>
#interface Population : NSObject
#property NSMutableArray *totalPopulation;
#property NSMutableArray *gaussianPopulation;
-(void)createPopulation; // test purpose to create uniform distribution. not used anymore.
-(void)createGaussianPopulation;
-(double)calculateAndersonDarling;
#end
and Population.m:
#import "Population.h"
#include <math.h>
#implementation Population
-(void)createPopulation
{
_totalPopulation = [[NSMutableArray alloc] init];
srandom((int)time(NULL));
NSNumber *randomNumber;
for (int i = 0 ; i < 10000 ; i++)
{
randomNumber = [[NSNumber alloc] initWithInt:random()];
[_totalPopulation addObject:randomNumber];
NSLog(#"%#", randomNumber);
}
}
-(void)createGaussianPopulation
{
for (int i = 0; i < 5000 ; i++)
{
double x1, x2, w, y1, y2;
do
{
x1 = 2.0 * ((double)arc4random() / ARC4RANDOM_MAX) - 1.0;
x2 = 2.0 * ((double)arc4random() / ARC4RANDOM_MAX) - 1.0;
w = x1 * x1 + x2 * x2;
} while (w >= 1.0);
w = sqrt((-2.0 * log(w))/w);
y1 = x1 * w;
y2 = x2 * w;
NSNumber *value1 = [NSNumber numberWithDouble:y1];
NSNumber *value2 = [NSNumber numberWithDouble:y2];
[self.gaussianPopulation addObject:value1];
[self.gaussianPopulation addObject:value2];
//NSLog(#"%# %#", value1, value2);
NSString *pathToDesktop = [NSString stringWithFormat:#"/Users/%#/Desktop", NSUserName()];
//make a file name to write the data to using the documents directory:
NSString *fileName = [NSString stringWithFormat:#"%#/testfile.tst", pathToDesktop];
//create content
NSString *content = [NSString stringWithFormat:#"%#\n%# \n", [value1 stringValue], [value2 stringValue]];
NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:fileName];
[myHandle seekToEndOfFile];
[myHandle writeData:[content dataUsingEncoding:NSUTF8StringEncoding]];
}
}
-(double)calculateAndersonDarling
{
NSLog((#"in method calculateAndersonDarling"));
NSLog(#"%i", [self.gaussianPopulation count]);
for (id eachObject in self.gaussianPopulation)
{
NSLog(#"%#", eachObject);
}
NSArray *sortedData = [NSArray arrayWithArray:[self.gaussianPopulation sortedArrayUsingSelector:#selector(compare:)]];
//NSArray *sortedData = [self.gaussianPopulation sortedArrayUsingSelector:#selector(compare:)];
NSLog(#"%i", [sortedData count]);
for (id eachObject in sortedData)
{
NSLog(#"%#", eachObject);
}
return 0.0; //return value to be done later
}
#end
As you can see (where the commented line is) I have tried different approaches.
But it seems like the sortedData array remains empty.
The size via NSLog is reported as zero and there is no output for the contents.
Any help would be appreciated.
just in case:
#import <Foundation/Foundation.h>
#import "Population.h"
int main(int argc, const char * argv[])
{
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
Population *myPopulation;
myPopulation = [[Population alloc] init];
[myPopulation createGaussianPopulation];
[myPopulation calculateAndersonDarling];
}
return 0;
}
NSLog output:
2014-09-12 16:46:44.647 Statistik[4158:303] Hello, World!
2014-09-12 16:46:45.154 Statistik[4158:303] in method calculateAndersonDarling
2014-09-12 16:46:45.154 Statistik[4158:303] 0
2014-09-12 16:46:45.155 Statistik[4158:303] 0
Program ended with exit code: 0
clearly the Array gaussianPopulation is already empty in the method calculateAndersonDarling, or is my calculation of the array size wrong?
But why should it have lost its contents???
You forgot to allocate the gaussianPopulation array before adding elements to it. In Objective-C you can call methods on nil objects, it won't have any effect (no crash, no warning). That's why it's sometimes difficult to see these bugs. Just initialize the array at the beginning of the method:
- (void)createGaussianPopulation
{
self.gaussianPopulation = [NSMutableArray array];
...

Self and arrays problems

I am new to Objective C and I'm having trouble getting my head around a few things.
I am trying to make a big integer program, from which I read items entered in a string and put them into an individual elements in the array.
I am currently working on an add method which adds elements from both the arrays together to make a big number stored in a final array.
But I'm kind of confused about to get this array I made from the initWithString method into the array method. I have some understanding of self, but I don't really know how to use it in this sense.
#implementation MPInteger
{
}
-(id) initWithString: (NSString *) x
{
self = [super init];
if (self) {
NSMutableArray *intString = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[intString addObject:ch];
}
}
return self;
}
-(NSString *) description
{
return self.description;
}
-(MPInteger *) add: (MPInteger *) x
{
//NSMutableArray *arr1 = [NSMutableArray arrayWithCapacity:100];
//NSMutableArray *arr2 = [NSMutableArray arrayWithCapacity:100];
//for (int i=0; i < 100; i++) {
//int r = arc4random_uniform(1000);
//NSNumber *n = [NSNumber numberWithInteger:r];
//[arr1 addObject:n];
//[arr2 addObject:n];
// }
self.array = [NSMutableArray initialize];
return x;
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
MPInteger *x = [[MPInteger alloc] initWithString:#"123456789"];
MPInteger *y = [[MPInteger alloc] initWithString:#"123456789"];
[x add: y];
}
}
So I want too add the x and y arrays, but I'm not sure how to get the arrays in the add method. Do I use self to represent one of the arrays and initialise it, and x to represent the other. I don't know if I'm going about it completely the wrong way. Some help to understand would be greatly appreciated.
When referring to self you're actually accessing the current instance of the class. In other languages this may be implemented as this instead. There are a couple ways of designing the approach you're going for but the simplest pattern is probably composition:
#interface MPInteger
{
NSMutableArray *digits;
}
#end
----------------------------------------------------------------------------
#implementation MPInteger
-(id) initWithString: (NSString *) x
{
// Create a new instance of this class (MPInteger) with a default
// constructor and assign it to the current instance (self).
self = [super init];
if (self) {
// Previously we initialized a string, but then threw it out!
// Instead, let's save it to our string representation:
self->digits = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[self->digits addObject:ch];
}
return self;
}
// Depending on how you want to implement this function, it could return
// a new MPInteger class or update the current instance (self):
-(MPInteger *) add: (MPInteger *) x
{
NSArray *a = self->digits;
NSArray *b = x->digits;
// Have both strings for A + B, so use them to find C:
NSArray *c = ????;
// Return a new instance of MPInteger with the result:
return [ [ MPInteger alloc ] initWithString:c ];
}
#end
Notice that now the MPInteger class has an instance of an NSString object that will exist during the entire lifetime of the MPInteger object. To update/access this string, all you need to do is say:
self->digits

Objective C Pointers

I am experiencing a very odd problem with pointers. As you could see from the below code, I am using a method that generates a random 4 by 4 character grid. It return a pointer to a two dimensional character array. The problem is that when i try to assign the returned pointer to another pointer and try to print the generated grid, I get just one strange symbol.
Header File
#import <Foundation/Foundation.h>
#interface GridGenerator : NSObject
{
}
-(char (*)[4]) generateGrid;
-(int (*)[2]) bbb;
-(void) print;
#end
Implementation File
#import "GridGenerator.h"
#implementation GridGenerator
-(char (*)[4])generateGrid{
char vowels[6] = {'A','E','I','O','U','Y'};
char consonants[20] = {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Z'};
char grid[4][4];
int vowelsLength = (sizeof vowels / sizeof vowels[0]);
int consLength = (sizeof consonants / sizeof consonants[0]);
int gridSize = (sizeof grid / sizeof grid[0]);
for(int i=0;i<gridSize;i++){
int vowelsInGridRow = 0;
int noOfVowels = (arc4random() % 2) + 1;
for(int j=0;j<gridSize;j++){
if(noOfVowels != vowelsInGridRow){
int vowIndex = arc4random() % vowelsLength;
char s = vowels[vowIndex];
grid[i][j] = s;
vowelsInGridRow++;
}
else{
int consIndex = arc4random() % consLength;
char s = consonants[consIndex];
grid[i][j] = s;
}
}
}
char (*sd)[4]= grid;
return sd;
}
-(void)print{
char (*grid)[4] = [self generateGrid];
NSString *s = #"\n";
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
s = [s stringByAppendingString:[NSString stringWithFormat:#"%c",grid[i][j]]];
}
s = [s stringByAppendingString:#"\n"];
}
NSLog(#"%#",s);
}
Main File(Test)
#import <Foundation/Foundation.h>
#import "Crossword.h"
#import "GridGenerator.h"
int main(int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GridGenerator *gen = [[GridGenerator alloc] init];
[gen print];
[pool release];
return 0;
}
When I run the code, you can see the result below. After the 'U' there is an inverted question mark(could not be pasted here).
2013-06-02 11:24:29.923 CrosswordTest[646:303]
U
Do you have an idea, what could causes this to happen? I am struggling already for several hours and I cannot find any explanation.
You are returning a reference to a temporary. Explosion (undefined behavior) should be expected.
Workaround. Create a structure:
typedef struct {char at[4][4];} t_grid;
Then populate and return the t_grid by value:
- (t_grid)generateGrid
{
char vowels[6] = {'A','E','I','O','U','Y'};
char consonants[20] = {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Z'};
t_grid grid;
...
int gridSize = (sizeof grid.at / sizeof grid.at[0]);
...
grid.at[i][j] = s;
...
return grid;
}
- (void)print
{
t_grid grid = [self generateGrid];
...
Note that you should not use this approach for large arrays or variable length arrays. 4*4 octets is small.

printing an array of arrays in objective C

Sorry for the simple question, but I am self taught and know that there are gaps in my education.
To print an array in objective C, I believe is:
NSLog(#"My array: %#", myArray);
How can I print an array of arrays?
Thanks
You want this:
for(NSArray *subArray in myArray) {
NSLog(#"Array in myArray: %#",subArray);
}
This will work for an array that has arrays nested one level deep.
You don't need to do anything different to log an array of arrays; the code exactly as you've written it will already show the contents of the sub-arrays.
That is, the following program:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [NSMutableArray array];
for (int i=0; i<5; ++i) {
NSMutableArray *sub = [NSMutableArray array];
for (int j=0; j<=i; ++j) {
[sub addObject:[NSString stringWithFormat:#"%d", j]];
}
[array addObject:sub];
}
NSLog(#"Array: %#", array);
[pool drain];
return 0;
}
Produces the following output:
Array: (
(
0
),
(
0,
1
),
(
0,
1,
2
),
(
0,
1,
2,
3
),
(
0,
1,
2,
3,
4
)
)
Clearly, it's already logging the sub-arrays just fine. If you want to control the formatting differently, you'd have to manually iterate them, but by default, the -description of an NSArray is little more than the -description of every object in that array, which includes all sub-arrays.
So I was embarrassed by the recursiveDescription thing, so I wrote my own as a category on NSArray. Note that this code will print out a description for an array of arrays to any depth. The description itself could probably use a bit more formatting than commas and newlines. Here you go:
#interface NSArray (RecursiveDescription)
- (NSString *)recursiveDescription;
#end
#implementation NSArray (RecursiveDescription)
- (NSString *)recursiveDescription {
NSMutableString *description = [[NSMutableString alloc] initWithString:#"Array (\n"];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (NSObject *child in self) {
if ([child respondsToSelector:#selector(recursiveDescription)]) {
[description appendFormat:#"%#,\n", [child recursiveDescription]];
}
else {
[description appendFormat:#"%#,\n", [child description]];
}
}
[pool drain];
[description appendString:#"\n)"];
return [description autorelease];
}
#end
Try logging the return value from NSArray's -description method.
NSLog(#"My array: %#", [myArray description]);
Moreover, for print all of elements
int i = 0;
int j = 0;
for(NSArray *subArray in myArray) {
NSLog(#"[%d] %#",i, subArray);
j =0;
for(NSObject *element in subArray) {
NSLog(#"[%d:%d] %#", i,j,element);
++j;
}
++i;
}
As much as I like how easy it is to log out an object in Objective-C, I didn't like seeing a 2D array as a very long list. I created a category on NSArray that prints out 2D arrays. It's not perfect and can be improved, but it has worked for me.
Header:
#interface NSArray (Logging)
- (void)log2DArray;
#end
Implementation:
#import "NSArray+Logging.h"
#implementation NSArray (Logging)
- (void)log2DArray {
NSMutableString *formattedString = [[NSMutableString alloc] init];
NSInteger longestSubarrayLength = 0;
for (NSArray *subarray in self) {
if (subarray.count > longestSubarrayLength) {
longestSubarrayLength = subarray.count;
}
}
for (int i = 0; i < longestSubarrayLength; i++) {
[formattedString appendFormat:#"\n"];
for (int j = 0; j < self.count; j++) {
NSArray *tempArray = [self objectAtIndex:j];
if (tempArray.count <= longestSubarrayLength) {
[formattedString appendFormat:#"%#\t", [tempArray objectAtIndex:i]];
} else {
[formattedString appendFormat:#"\t"];
}
}
}
NSLog(#"%#", formattedString);
}
#end
Usage:
[myArray log2DArray];
Or use recursiveDescription :)
NSLog(#"my arrays: %#", [myArray recursiveDescription]);