How to pass double[][] into a method call? - iphone

Hi I am trying to init an object with a double value in the format double filter[3][3];
but i keep getting the following error.
cannot convert 'double[3][3]' to 'double' in assignment.
in my header i have this
#interface filter : NSObject
{
double **matrix;
}
#property(nonatomic)double **matrix;
-(id)initWithMatrix:(double**)filterMatrix;
inside my class i have this method.
-(id)initWithMatrix:(double**)filterMatrix
{
matrix = filterMatrix;
return self;
}
and i am trying to call it like this.
double filter[3][3] = {0,0,0,0,1,0,0,0,0};
MyMatrix *myMatrix = [[MyMatrix alloc] initWithMatrix:filter];
I now get the error.
Error: Cannot convert double[*][3] to double** in argument passing
Any help on this issue would be amazing.
Thanks
A

That's because double** isn't the equivalent of double[*][*]. In fact, double[*][*] is an invalid type, because it leaves the stride undefined. double** is a pointer to a pointer to a double, or to put it another way, it's a pointer to an array of doubles. You should just use double* as your type.
Edit: To clarify, double[*][3] is still just an array of doubles, even though it has 2 dimensions. This is still the equivalent of double*.

A two-dimensional array is not the same thing as a pointer-to-a-pointer. You have two choices - change the filter class to contain a 2D array, or change your initialization to use pointer-to-pointers.
In choice #1, you're could keep a copy of the array in your filter instance, instead of just holding a pointer. You need to change the class interface:
#interface filter : NSObject
{
double matrix[3][3];
}
-(id)initWithMatrix:(double[3][3])filterMatrix;
Then your implementation of initWithMatrix: can just do a memcpy() or the equivalent to copy the data into your instance.
Choice #2 is a bit different. Keep your other code the way it is, but change your initialization of filter:
double row0[3] = {0,0,0};
double row1[3] = {0,1,0};
double row2[3] = {0,0,0};
double **filter[3] = { row0, row1, row2 };
It's probably safer to malloc() all of those arrays, since otherwise you're going to end up with references to stack variables in your filter class, but I think you get the idea.

you are passing as a parameter a double 2d array(double[][]) when your method signature asks for a double (a primitive like 34.2).
set the method declaration to
- (id)initWithMatrix:(double*) matrix;
this passes a pointer to your array (2d) to the method.
edit: missed a semicolon.

Related

How to assign method output to variable by reference MQL4

I'm guessing this question is going to apply to many similar languages other than MQL4 such as c++ (which I also forget how to use) which require you manually specify when you are passing by reference.
Method reference:
int[] previous = GetPrevious(i, ZigZagBuffer);
Method definition:
int GetPrevious[](int current, const double& buffer[])
{
int count = 0;
int result[];
// calculate count
ArrayResize(result,count);
// fill array
return result;
}
The resulting compile error is:
"Invalid Array Access"
From what I understand, this is because array's can only be passed by reference, but you have to explicitly state that you are passing it by reference. But the more I look up the syntax for passing by reference, the more I find articles about passing parameter by reference. (which I already know how to do as you can see in the code example.)
What is the syntax to assign the output of a method to a variable?
In case it matters, I only need to read the array multiple times; I'm not needing to alter or re-assign it after it is declared.
You cannot return array. You have to create it and pass into the function, fill inside the function and that's it.
OnTick(){
double array[]; //declaration of the array
fillArray(array,10); //passing array by ref, updating it there
Print(array[0]=0 && array[9]=9);//returns true
}
void fillArray(double &array[],int size){
ArrayResize(array,size);
for(int i=0;i<size;i++){array[i]=i;}
}

Accessing elements of a struct instance variable in Objective-C using the getter

I have an instance variable which is a struct, for example:
struct Data {
UInt32 i;
UInt32 arr[1];
};
And a property is defined in my class:
#property struct Data data; // and the corresponding #synthesize in the imp file
Now, I am aware that changing the values of i and arr through the getter of data is conceptually wrong, since I will be accessing the copy of data returned by the getter (the correct way is accessing it using self->data).
However some general Objective-C questions arise regarding the following lines:
self.data.i = 1; // produces compile error
self.data.arr[0] = 1; // compiles ok
First, why does the first line produces a compile error, and the 2nd line does not?
Second, if the dot syntax in the above line (self.data) is just a syntactic sugar to [self data], why do I get 2 different (although similar) compile errors?
self.data.i = 1; // error: Expression is not assignable
[self data].i = 1; // error: Semantic Issue: Assigning to 'readonly' return result of an objective-c message not allowed
Actually, structs are passed by value in C (and Objective C). That means that your property actually returns a read only copy (rvalue) of the internal "Data" type. The assignment is to the temporary returned copy, which the compiler (rightfully) flags as a bit suspect.
The second line that compiles correctly does so since self.data.arr returns a read only UInt32*, but when you index it with [0] and write to that, you're not writing to the pointer, you're writing to the memory that it points to which is allowed.

Function returning an array in ObjC for iPhone

Hello
I am trying to make this function to return an array! What is going wrong here?
-(char[10])print01:(int)int11{ //error: declared as method returning an array
char arrayT[10];
for(int i=0;i<8;i++)
{
if ((int1-n1)>=0){
arrayT[i]='1';
int1-=n1;
}
else
arrayT[i]= '0';
n1=n1/2;
}
return arrayT[]; // incompatible types in return
}
and I want to call it like that:
char array1[10] = [self print01:(int)int1]; //error: invalid initializer
any suggestions please?
You can't return an array in C or in Objective-C. The best you can hope for is to return a pointer to an array, but if you're going to do that, make sure you don't return a pointer to an array on the stack (like yours is).
The best approach is using an NSArray (of objects of course, I'm assuming the above code is simplified sample, but you can always use an NSNumber). Alternatively, you could return a pointer to an array, which is common in C as C (and objective c by extension) cannot return an array. Unfortunately, this would require allocating memory for the array and using manual memory management, (malloc/free) which depending on the lifecycle of the array, can be anywhere from a nuisance to awful. My recommendation is taking a char *dest parameter, and inserting chars into the array as dest[i]

NSAllocateCollectable it is possible with iPhone application?

I'm developing an iphone application and when I compile it I receive some warnings. The application works, but probably it is interesting to delete all the warnings no?
This is one of them, that I can't undersand, basically because I'm a "rookie" with iPhone SDK and this class comes from another code (free code).
The warning are:
warning: implicit declaration of function 'NSAllocateCollectable'
warning: initialization makes pointer from integer without a cast
The code is this:
double *MatrixAllocateArray( NSUInteger rows, NSUInteger columns )
{
// Allocate an array to hold [rows][columns] matrix values
NSCParameterAssert(rows!=0);
NSCParameterAssert(columns!=0);
__strong double *array = NSAllocateCollectable(SIZEOFARRAY(rows,columns),0); //(WARNINGS APPEAR HERE)
NSCAssert2(array!=NULL,#"falled to allocate %dx%d matrix",rows,columns);
return array;
}
As you can see this function try to allocate a matrix, and it is called by another function.
double *MatrixAllocateEmptyArray( NSUInteger rows, NSUInteger columns )
{
// Allocate a matrix array and fill it with zeros
__strong double *emptyArray = MatrixAllocateArray(rows,columns);
bzero(emptyArray,SIZEOFARRAY(rows,columns));
return emptyArray;
}
And this is called by the function which I execute and need:
- (id)initWithRows:(NSUInteger)rowCount columns:(NSUInteger)colCount
{
// Create an empty matrix
return [self initWithAllocatedArray:MatrixAllocateEmptyArray(rowCount,colCount)
rows:rowCount
columns:colCount];
}
There's no garbage collector for iPhone programs. Allocating collectable memory is pretty much meaningless in that sitaution, so you're probably out of luck. You should probably fix your program and/or framework to use the traditional Objective-C memory management practices. The reasons for your specific warnings:
implicit declaration of function 'NSAllocateCollectable'
There is no declaration of NSAllocateCollectable for your iPhone app, so the compiler is going to fall back to the default C rules for implicit function declarations, meaning it will assume it returns int.
initialization makes pointer from integer without a cast
Because of the previous problem with the implicit declaration, your code looks to the compiler like it is trying to assign an int to a variable of type double * - implicit conversions from integer types to pointers are a cause for warnings.

how to pass a double with [n][n] values into a method [duplicate]

Hi I am trying to init an object with a double value in the format double filter[3][3];
but i keep getting the following error.
cannot convert 'double[3][3]' to 'double' in assignment.
in my header i have this
#interface filter : NSObject
{
double **matrix;
}
#property(nonatomic)double **matrix;
-(id)initWithMatrix:(double**)filterMatrix;
inside my class i have this method.
-(id)initWithMatrix:(double**)filterMatrix
{
matrix = filterMatrix;
return self;
}
and i am trying to call it like this.
double filter[3][3] = {0,0,0,0,1,0,0,0,0};
MyMatrix *myMatrix = [[MyMatrix alloc] initWithMatrix:filter];
I now get the error.
Error: Cannot convert double[*][3] to double** in argument passing
Any help on this issue would be amazing.
Thanks
A
That's because double** isn't the equivalent of double[*][*]. In fact, double[*][*] is an invalid type, because it leaves the stride undefined. double** is a pointer to a pointer to a double, or to put it another way, it's a pointer to an array of doubles. You should just use double* as your type.
Edit: To clarify, double[*][3] is still just an array of doubles, even though it has 2 dimensions. This is still the equivalent of double*.
A two-dimensional array is not the same thing as a pointer-to-a-pointer. You have two choices - change the filter class to contain a 2D array, or change your initialization to use pointer-to-pointers.
In choice #1, you're could keep a copy of the array in your filter instance, instead of just holding a pointer. You need to change the class interface:
#interface filter : NSObject
{
double matrix[3][3];
}
-(id)initWithMatrix:(double[3][3])filterMatrix;
Then your implementation of initWithMatrix: can just do a memcpy() or the equivalent to copy the data into your instance.
Choice #2 is a bit different. Keep your other code the way it is, but change your initialization of filter:
double row0[3] = {0,0,0};
double row1[3] = {0,1,0};
double row2[3] = {0,0,0};
double **filter[3] = { row0, row1, row2 };
It's probably safer to malloc() all of those arrays, since otherwise you're going to end up with references to stack variables in your filter class, but I think you get the idea.
you are passing as a parameter a double 2d array(double[][]) when your method signature asks for a double (a primitive like 34.2).
set the method declaration to
- (id)initWithMatrix:(double*) matrix;
this passes a pointer to your array (2d) to the method.
edit: missed a semicolon.