Icomplete implementation and Pointer conversion error. - objective-c

Compiler warning(1): Incomplete implementation
I've compared my .h and .m files to see any inconsistencies or spelling mistakes between whats declared and implemented and can't find any.
Compiler warning(2): Incompatible integer to pointer conversion sending 'NSInteger*' (aka 'int*') with and expression of type 'int'.
I've been mucking about with asterisks for 25 minutes in all sorts of combinations and the compiler is still unhappy.
#import "Game.h"
#import "stdlib.h"
const int MAXRAND = 15;
const int MAXCOL = 7;
const int MAXROW = 9;
NSInteger gameState[MAXROW][MAXCOL];
NSInteger answerBoard[MAXROW][MAXCOL];
#implementation Game//compiler warning 1
-(void)init:(NSInteger*) rows: (NSInteger*) columns: (NSInteger*) operators:(NSInteger*) operands{
NSLog(#"init sent");
numRows = *rows;
numColumns = *columns;
numOperators = *operators;
numOperands = *operands;
//seed random number generator
//generate rand nums for operands
int operandList[numOperands];
for (int i = 0; i < numOperands; i++) {
srandom(time(NULL));
operandList[i] = (random()%MAXRAND);
}
//generate state and answer board
BOOL gameState[numRows][numColumns];
NSInteger answerBoard[numRows][numColumns];
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numColumns; j++) {
gameState[i][j] = NO;
answerBoard[i][j] = (operandList[random()%numOperands])+
(operandList[random()%numOperands])-
(operandList[random()%numOperands]);
}
}
}
-(void)updateGame:(NSInteger*)enteredNum{
NSLog(#"updateGame sent");
for (int i = numColumns; i > 0; i--) {
for (int j = numRows; j > 0; j--) {
if (gameState[i][j] == NO){
if (*enteredNum == answerBoard[i][j]){
gameState[i][j] = YES;
}
}
}
}
}
#end//Game
#import <Foundation/Foundation.h>
#interface Game : NSObject
{
NSInteger numRows, numColumns, numOperators, numOperands;
}
-(void)init:(NSInteger*) rows: (NSInteger*) columns: (NSInteger*) operators:(NSInteger*) operands;
-(void)updateGame:(NSInteger*) enteredNum;
#end
Where the instance of my class is declared and initialized:
NSInteger *rows = 7, *columns = 6, *operators = 2, *operands = 6;//compiler warning 2
Game *game = [Game new];
[game init:rows :columns :operators :operands];

NSInteger *rows = 7, *columns = 6, *operators = 2, *operands = 6;
rows,columns, operators, operands are of type NSInteger *. You need to allocate memory and then need to place 7,6,2,6 in the memory locations they are pointing at. In C-terms,
int *ptr = 7; // Wrong. Because, ptr is pointing no where to keep 7 in that location.

Did you try?
NSInteger rows = 7, columns = 6, operators = 2, operands = 6;
And what is?
[Game new];
The compiler is probably expecting you to implement a function named new.
EDIT:
Try removing all '*' from your NSInteger's.

Related

Project Euler # 10 in Objective C

I'm trying to solve Problem 10 in Project Euler, and while I thought I had it, its saying my answer is incorrect. The question is as follows:
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
And my code:
int sum;
#interface Prime : NSObject
-(BOOL)isPrime:(int)arg1;
#end
#implementation Prime
-(BOOL)isPrime:(int)arg1 {
if (arg1 == 1) {
NSLog(#"Given 1");
return NO;
}
for (int i = 2; i < arg1; i++) {
if (arg1 % i == 0) {
return NO;
}
}
sum += arg1;
return YES;
}
#end
int main(int argc, const char * argv[])
{
#autoreleasepool {
Prime* primeObject = [[Prime alloc] init];
for (int i = 0; i < 2000000; i++) {
[primeObject isPrime:i];
}
NSLog(#"Sum of primes is %i", sum);
}
}
This code outputs 'Sum of primes is 1179908154' which Project Euler says is incorrect. Help?
The problem is that the sum does not fit into a 32-bit integer. You should use long long instead.
Just a guess, you should try to:
Initialise the sum variable to 0.
Try not to use a global variable like sum that can be accessed from anywhere, in this case do the sum in the main loop instead of in the isPrime method.
Maybe that'll give you the right answer.
You are using int for getting result, so it is wrong.
I'm using long int instead, that is enough for this case.
Here is my code, and it works fine:
int inputNumber = 2000000;
long int result = 0;
for (int i = 2; i < inputNumber; i++) {
BOOL isPrime = YES;
for (int j = 2; j <= sqrt(i); j++) {
if (i%j==0) {
isPrime = NO;
break;
}
}
if (isPrime) {
result += i;
}
}
Result is: 142913828922

exc_bad_access (code= 2 address =0x0)

I am new to this, trying to make an Minesweeper iphone app
i used a IBButton to Reset mine fields
which is a 2 by 2 matrix of a struct
- (IBAction) Reset {
for (int x = 0 ; x < 10 ; x ++) {
for (int y = 0 ; y < 10 ; y++ ) {
f[x][y]->isOpen = NO;
f[x][y]->display = 0; //Going to make a search function for finding Number of mines next to it
int random = arc4random()%10;
if (random < 2) {
f[x][y]->isMine = YES;
} else {
f[x][y]->isMine = NO;
}
}
}
so i get the the error at the very first line of my for loop
f[x][y]->....
what did i do wrong here?
/edit
This is how i declared my f
struct feild *f[10][10];
struct feild{
bool isOpen;
bool isMine;
int display;
}
You haven't allocated any space for f, so f[x][y] will just contain junk memory and then the ->isOpen = NO access will blow up.
you need to do something like
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
f[i][j] = malloc(sizeof(struct feild));
}
}
before your code.

How to return generated array from c function to objective-c

Need to generated some random 10 byte length string in c function and call the function from objective-c. So, I'm creating a pointer to uint8_t and passing it to C function. The function generates random bytes and assigns them to *randomString. However, after returning from function to objective-c randomValue pointer points to NULL.
Here's my random function in C:
void randomString(uint8_t *randomString)
{
randomString = malloc(10);
char randomByte;
char i;
for (i = 0; i < 10; i++) {
srand((unsigned)time(NULL));
randomByte = (rand() % 255 ) + 1;
*randomString = randomByte;
randomString++;
}
}
Here's objective-c part:
uint8_t *randomValue = NULL;
randomString(randomValue); //randomValue points to 0x000000
NSString *randomString = [[NSString alloc] initWithBytes:randomValue length:10 encoding:NSASCIIStringEncoding];
NSLog(#"Random string: %#", randomString);
A more natural semantic, like malloc() itself would be:
uint8_t * randomString()
{
uint8_t *randomString = malloc(10);
srand((unsigned)time(NULL));
for (unsigned i = 0; i < 10; i++)
randomString[i] = (rand() % 254) + 1;
return randomString;
}
Pointers are passed by value, so randomValue will remain NULL after the call of randomString. You need to pass a pointer to a pointer in order to make it work:
void randomString(uint8_t **randomString) {
*randomString = malloc(10);
// ... the rest of your code goes here, with an extra level of indirection
}
uint8_t *randomValue = NULL;
randomString(&randomValue);
You probably should be using uint8_t **randomeValue instead of uint8_t *.

NSFastEnumeration crashing on C array with ARC

I'm initializing a C array of objects and setting the first element:
id __strong *_objs = (id __strong *)calloc(16,sizeof(*_objs));
_objs[0] = #1;
_count++;
Then I'm using the following implementation of NSFastEnumeration:
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
objects: (id __unsafe_unretained*)stackbuf
count: (NSUInteger)len
{
NSUInteger size = _count;
NSInteger count;
state->mutationsPtr = (unsigned long *)size;
count = MIN(len, size - state->state);
if (count > 0)
{
IMP imp = [self methodForSelector: #selector(objectAtIndex:)];
int p = state->state;
int i;
for (i = 0; i < count; i++, p++) {
stackbuf[i] = (*imp)(self, #selector(objectAtIndex:), p);
}
state->state += count;
}
else
{
count = 0;
}
state->itemsPtr = stackbuf;
return count;
}
Unfortunately it crashes with EXC_BAD_ACCESS when I run it:
for (id object in array){ // EXC_BAD_ACCESS
NSLog(#"%#",object)
}
Any idea why?
If you have CodeRunner, here is an executable version.
The problem is the mutationsPtr which points to the memory address 1 which you are not allowed to access (and which is not 4 byte aligned as well):
state->mutationsPtr = (unsigned long *)size;
Replace it with a valid pointer for starters (careful: the one below may make no sense at all in your scenario, but at least it fixes the EXC_BAD_ACCESS):
state->mutationsPtr = (unsigned long *)&_count;
#Jano
In case you want to get rid of the compiler warning you will get with recent versions of Xcode (4.6) for
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
objects: (id __unsafe_unretained*)stackbuf
count: (NSUInteger)len
because it does not match the original prototype for objects:..stackbuf
- (NSUInteger) countByEnumeratingWithState: (NSFastEnumerationState*)state
objects: (__autoreleasing id *)stackbuf
count: (NSUInteger)len
see Todd Lehmans answer in Automatic Reference Counting: Error with fast enumeration

Placing a method in a seperate file to make code more readable

I have a method which has gotten a little long & I want to place it in its own file. It's not useful outside the program I'm working on, I really just want to remove it so that my code is more readable.
The method is below,
- (void)randomiseAudioIndicesBeforeInitialPlay
{
int numberOfStems = 20;
index = malloc(numberOfStems*sizeof(int));
for (int i = 0; i < numberOfStems; i++)
{
index[i] = i;
}
for (int i = (numberOfStems - 1); i > 0; i--)
{
int randomIndex = arc4random() % i;
int tmp = index[i];
index[i] = index[randomIndex];
index[randomIndex] = tmp;
}
}
I tried making a subclass as per this previous question
//RandomiseStems.h
#import <Foundation/Foundation.h>
#interface RandomiseStems : UIViewController {
int *index;
}
#property(nonatomic, readwrite) int *index;
- (void)randomiseAudioIndicesBeforeInitialPlay;
#end
//RandomiseStems.m
#import "RandomiseStems.h"
#implementation RandomiseStems
#synthesize index;
- (void)randomiseAudioIndicesBeforeInitialPlay
{
NSLog(#"randomise called");
int numberOfStems = 20;
//int* index = malloc(numberOfStems*sizeof(int));
index = malloc(numberOfStems*sizeof(int));
for (int i = 0; i < numberOfStems; i++)
{
index[i] = i;
}
for (int i = (numberOfStems - 1); i > 0; i--)
{
int randomIndex = arc4random() % i;
int tmp = index[i];
index[i] = index[randomIndex];
index[randomIndex] = tmp;
//free index
}
}
#end
I then import the .h into my viewController.h file & my .m file into my viewController.m file. It's builds ok but when I try to call randomiseAudioIndicesBeforeInitalPlay it throws an exception (i used
[self randomiseAudioIndicesBeforeInitalPlay];)
Is this a valid way to do this? if so any ideas on how it might be fixed? thanks in advance :)
If you just want to move a method, or a few, a Category is the way to go, that is what they are designed for. What you can't do is create any new ivars.