float array gives different datas at the end of it in objective c - objective-c

I bumped to a strange error.(at least for me) I am trying to use float array in FFT and audio filters that I apply. but float array gives different datas at the end.
I define a global pointer. I point a float array to it. but when I try to use the pointer in somewhere out of the scope of a method, the last 100-150 datas of 441000 datas get mostly 0 or some other very big numbers. I dont understand how a data can change when I use somewhere in out of scope
in scope I loop in it and every data is correct but when I try to loop outside of the scope of the method I created the array, it gives different datas at the end.
#interface ViewController ()
{
float *filteredData;
int theFileLengthInFrames;
}
#end
#implementation ViewController
..
..
-(void)FilterData:(float * ) rawData
{
int count = theFileLengthInFrames;
float filteredRawData[count];
for (int i = 0; i<count; i++)
{
filteredRawData[i] = rawData[i];
printf("%d_%f ",i,filteredRawData[i]);
//I check here to see the data . In here it is normal
}
filteredData = filteredRawData;
}
-(void) CalculateFFT
{
int numSamples = theFileLengthInFrames;
for (int i = 0; i<numSamples; i++)
{
printf("%d_%f ",i,filteredData[i]);
//when I check here to see the data , the last around 100 data are 0.00000 or some big number such as 250399682724883753288597504.000000
}
}
need help thanks

Your FilterData: method points the instance variable filteredData to a local array filteredRawData. Since filteredRawData is allocated on the stack, it becomes invalid when FilterData: returns. Then filteredData is a dangling pointer, and using it results in undefined behavior.
Solution: allocate persistent storage for filteredData. I would do it like this:
#implementation ViewController {
NSMutableData *filteredDataStorage;
float *filteredData;
}
-(void)FilterData:(float * ) rawData {
int count = theFileLengthInFrames;
filteredDataStorage = [NSMutableData dataWithLength:count * sizeof *rawData];
filteredData = (float *)filteredDataStorage.mutableBytes;
for (int i = 0; i<count; i++) {
filteredRaw[i] = rawData[i];
printf("%d_%f ",i,filteredRawData[i]);
//I check here to see the data . In here it is normal
}
}
Using NSMutableData for the persistent storage lets ARC take care of deallocating it when you call FilterData: again, or when ViewController is deallocated.

filteredData - The float pointer is an ivar, it's scoped to your object instance.
filteredRawData is defined at method scope. It's an array located on the stack. When filteredRawData goes out of scope that memory is no longer valid. Reading from it is undefined at best and could result in an access violation. You probably want to use malloc to dynamically allocate memory for your data, or have a global buffer defined for you to play with.

Related

Properly declare 2D array of Ints [duplicate]

I have the following code which works fine...
int testarr[3][3] = {
{1,1,1},
{1,0,1},
{1,1,1}
};
[self testCall: testarr];
Which calls this function:
- (void)testCall: (int[3][3]) arr {
NSLog(#"cell value is %u",arr[1][1]);
}
I need the array to be of variable length - What is the best way to declare the function?
Using blanks doesn't work:
- (void)testCall: (int[][]) arr {
Thanks for your help.
I would write this as:
- (void) testCall: (int *) aMatrice;
Doing so allows you to avoid multiple mallocs and the math to calculate a single offset in a linear array based on x, y coordinates in a 2D array is trivial. It also avoids the multiple mallocs implied by int** and the limitations of 2D array syntax perpetuated by the language.
So, if you wanted a 4x5 array, you might do:
#define WIDTH 4
#define HEIGHT 5
#define INDEXOF(x,y) ((y*WIDTH) + x)
int *myArray = malloc(sizeof(int) * 5 * ELEMS_PER_ROW);
You could then initialize the array linearly or with a nested for loop:
for(int x=0; x<width; x++)
for(int y=0; y<height; y++)
myArray[INDEXOF(x,y)] = ... some value ...;
And you would pass it to the method like:
[foo testCall: myArray];
Though you might want to also carry along the width and the height or, better yet, create a IntMatrix subclass of NSObject that wraps all of the pointer arithmetic and storage beyond a nice clean API.
(all code typed into SO)
C arrays can't be variable in more than one dimension.
You can't have this:
int testarr[][] = {
{1,1,1},
{1,0,1,2},
{1,1}
};
But you can have this:
int testarr[][3] = {
{1,1,1},
{1,0,1},
{1,1,1},
{4,5,6},
{7,8,9}
}
foo(testarr);
void foo(int param[][3])
{
printf("%d", param[3][1]); // prints 5
}
You can't use int[][] because the size of the second dimension affects how the array is laid out in memory. If you know the second dimension you can use int[][x], otherwise you'll have to use int** which can be accessed just like an array.
Why don't you just use NSArray or NSMutableArray with NSIntegers? Those array classes are of variable length, and much easier to use.
This would result in
- (void)testCall: (NSArray *) arr {
NSLog(#"cell value is %u", [[arr objectAtIndex:1] objectAtIndex:1]);
}
(Of course, you would also have to define testarr using NSArray.)
If you really want to use C arrays, making the method argument a pointer to an int with
- (void)testCall: (int*) arr {
will probably work (with the rest of the code staying the same).
call
int testarr[3][3] = {
{1,1,1},
{1,0,1},
{1,1,1}
};
[self testCall: (int *)testarr];
function
- (void)testCall: (int *) arr
{
int (*V_arr)[3] = (int(*)[3])arr;
NSLog(#"cell value is %u",V_arr[1][1]);
}

How to return a C-style array of integers in Objective-C?

How to return a C-style array of integers from an Objective-C method? This is what my code looks like so far:
Function call:
maze = [amaze getMaze];
Function:
-(int*) getMaze{
return maze;
}
I just started writing in Objective-C today so this is all new to me.
In C if you need to return an array from a function, you need to allocate memory for it using malloc and then return the pointer pointing to the newly allocated memory.
Once you're done working with this memory you need to free it.
Something like:
#include <stdlib.h> /* need this include at top for malloc and free */
int* foo(int size)
{
int* out = malloc(sizeof(int) * size); /* need to get the size of the int type and multiply it
* by the number of integers we would like to return */
return out; /* returning pointer to the function calling foo().
* Don't forget to free the memory allocated with malloc */
}
int main()
{
... /* some code here */
int* int_ptr = foo(25); /* int_ptr now points to the memory allocated in foo */
... /* some more code */
free(int_ptr); /* we're done with this, let's free it */
...
return 0;
}
This is as C style as it gets :) There are probably other (arguably more suitable) ways to do this in Objective C. However, as Objective C is considered a strict superset of C, this would also work.
If I may further expand on the need to do this by pointers. C-style arrays allocated in a function are considered local, once the function is out of scope they are automatically cleaned up.
As pointed out by another poster, returning a standard array (e.g. int arr[10];) from a function is a bad idea as by the time the array is returned it no longer exists.
In C we get around this problem by allocating memory dynamically using malloc and having a pointer that points to that memory returned.
However unless you free this memory adequately, you may introduce a memory leak or some other nasty behavior (e.g. free-ing a malloc-ed pointer twice will produce unwanted results).
Given you explicitly ask about C-style arrays no suggestions here that you should use NSArray etc.
You cannot return a C-style array directly (see below) as a value in Objective-C (or C or C++), you can return a reference to such an array.
Types such as int, double and struct x can all be passed by value - that is the actual bits representing the value are passed around. Other things; such as C-style arrays, dynamically allocated memory, Objective-C style objects, etc.; are all passed by reference - that is a reference to a location in memory that contains the actual bits the represent the value is passed around.
So to return a C-style array from a function/method you can:
Dynamically (malloc et al) an array and return the reference to the allocated memory;
Pass in a reference to an already existing array and have the function fill it up; or
Wrap the array up as a struct...
The normal choices are (1) or (2) - note you cannot return a reference to a stack allocated array, as in:
int *thisIsInvalid()
{
int myValues[5];
...
return myValues; // will not work, the type is correct but once function
// returns myValues no longer exists.
}
If you really want to return a (small) array by value you can actually do it using (3). Remember that struct values are passed by value. So the following will work:
typedef struct
{
int array[5];
} fiveInts;
fiveInts thisIsValid()
{
fiveInts myValues;
...
myValues.array[3] = ...; // etc.
...
return myValues;
}
(Note that there is no overhead from wrapping the array inside a struct when it comes to reading/writing the array - the cost in the above is copying all the values back - hence only advised for small arrays!)
HTH
- (NSArray *)toArray:(int *)maze {
NSMutableArray *retVal = [[NSMutableArray alloc] init];
for (int c = 0; maze[c] != NULL; c++) {
[retVal addObject:[NSNumber numberWithInt:maze[c]]];
}
return [retVal array];
}
I've never been comfortable passing mutable data in and out of methods and not sure why. If you need to change the values later, send the array a mutableCopy message.
you can do it in this way
- (void)getArray:(int *)array withLength:(NSUInteger)length{
for (int i = 0; i < length; i++)
array[i] = i;
}
int array[3];
[object getArray:array withLength:3];
NSLog(#"%d %d %d", array[0], array[1], array[2]); // 1 2 3

2D Array Declaration - Objective C

Is there a way to declare a 2D array of integers in two steps? I am having an issue with scope. This is what I am trying to do:
//I know Java, so this is an example of what I am trying to replicate:
int Array[][];
Array = new int[10][10];
Now, in OBJ-C I want to do something similar, but I cant get the syntax right. Right now I have it in one step, but I cannot use it outside of the If-Statement in which I currently have it:
int Array[10][10]; //This is based on an example I found online, but I need
//to define the size on a seperate line than the allocation
Can anyone help me out with this? I know its probably a more basic question, but you can't use the keyword "new" outside of a message (to my knowledge) and you cant send messages to ints. :(
*EDIT 1:**
My problem is scope related.
//Declare Array Somehow
Array[][] //i know this isn't valid, but I need it without size
//if statement
if(condition)
Array[1][2]
else
Array[3][4]
//I need to access it outside of those IFs
//... later in code
Array[0][0] = 5;
This is my preferred way of creating a 2D array, if you know the size of one of the boundaries:
int (*myArray)[dim2];
myArray = calloc(dim1, sizeof(*myArray));
And it can be freed in one call:
free(myArray);
Unfortunately, one of the bounds MUST be fixed for this to work.
However, if you don't know either of the boundaries, this should work too:
static inline int **create2dArray(int w, int h)
{
size_t size = sizeof(int) * 2 + w * sizeof(int *);
int **arr = malloc(size);
int *sizes = (int *) arr;
sizes[0] = w;
sizes[1] = h;
arr = (int **) (sizes + 2);
for (int i = 0; i < w; i++)
{
arr[i] = calloc(h, sizeof(**arr));
}
return arr;
}
static inline void free2dArray(int **arr)
{
int *sizes = (int *) arr;
int w = sizes[-2];
int h = sizes[-1];
for (int i = 0; i < w; i++)
free(arr[i]);
free(&sizes[-2]);
}
The declaration you showed (e.g. int Array[10][10];) is OK, and will be valid for the scope it was declared to, if you do it in a class scope, then it will be valid for the whole class.
If the size of the array varies, either use dynamic allocation (e.g. malloc and friends) or use NSMutableArray (for non-primitive data types)

Returning C struct array

Hello stackoverflow fellow members?
Struct Declaration in class A
struct PointSprite
{
GLfloat x;
GLfloat y;
GLfloat size;
Color4f color;
} ParticleSystems[MAXIMUM_PARTICLES_ON_SCREEN];
// I generally put some stuffs in ParticleSystem array.
// for ex) struct PointSprite *ps = &ParticleSystems[index];
// and it works well on the class A, but I want to get class B to access this array.
My question is, how am I suppose be return the array of 'ParticlelSystems' array so that other class can access to it? I have tried below code to return the pointer, but compiler gives me a warning.
- (struct ParticleSystems *) commitParticles
{
struct ParticleSystems *ptr = &ParticleSystems; // it said, assigning incompatible pointer type
return ptr;
}
Or should I need to allocate the 'ParticleSystems' array? Please help ! Thanks
If you are creating the array inside the function then you should dynamically allocate it using new and then return a pointer to it.
You cannot return arrays from a function, you will have to return a pointer to it.
Sample Code:
ParticleSystems* doSomethingInteresting()
{
ParticleSystems *ptr = new ParticleSystems[MAXIMUM_PARTICLES_ON_SCREEN];
//do the processing
return ptr;
}
The caller takes the ownership of the returned dynamically allocated array and needs to deallocate it to avoid memory leaks:
delete []ptr;
You can either return it, after allocating one, or you can fill one passed to you by the user. The latter leaves the responsibility to the user to provide a ParticleSystem to the method which receives the data. It can be a local array, or a malloced one.
- (void) commitParticles: (ParticleSystems *) sprites
{
// set members of the structs here
}
I prefer this kind of passing to returning a malloced array. Your mileage may vary.
You're getting the assigning incompatible pointer type compiler warning because your ptr declaration should be of type PointSprite *, not ParticleSystems *

qsort on an array of pointers to Objective-C objects

I have an array of pointers to Objective-C objects. These objects have a sort key associated with them. I'm trying to use qsort to sort the array of pointers to these objects. However, the first time my comparator is called, the first argument points to the first element in my array, but the second argument points to garbage, giving me an EXC_BAD_ACCESS when I try to access its sort key.
Here is my code (paraphrased):
- (void)foo:(int)numThingies {
Thingie **array;
array = malloc(sizeof(deck[0])*numThingies);
for(int i = 0; i < numThingies; i++) {
array[i] = [[Thingie alloc] initWithSortKey:(float)random()/RAND_MAX];
}
qsort(array[0], numThingies, sizeof(array[0]), thingieCmp);
}
int thingieCmp(const void *a, const void *b) {
const Thingie *ia = (const Thingie *)a;
const Thingie *ib = (const Thingie *)b;
if (ia.sortKey > ib.sortKey) return 1; //ib point to garbage, so ib.sortKey produces the EXC_BAD_ACCESS
else return -1;
}
Any ideas why this is happening?
The problem is two fold:
the first argument to qsort needs to be a pointer to the beginning of the array
the arguments passed to your sort function are actually pointers to the pointers of your data
Consider this working code:
int thingieCmp(const void *a, const void *b) {
NSObject *aO = *(NSObject **)a;
NSObject *bO = *(NSObject **)b;
if (aO.hash > bO.hash) return 1;
else return -1;
}
int main (int argc, const char * argv[]) {
NSObject **array;
array = malloc(sizeof(NSObject*)*20);
for(int i = 0; i < 20; i++) {
array[i] = [NSObject new];
}
qsort(array, 20, sizeof(NSObject*), thingieCmp);
return 0;
}
Note that the comparison function resolves the data pointers by NSObject *aO = *(NSObject **)a and the qsort function takes array as an argument directly.
All of this, though, begs the question of Why bother?
NSArray is very good at holding arrays of objects and is quite conveniently sortable. Performance is excellent in the general case. If performance analysis indicates that it isn't, you can optimize it away relatively easily.
Note, also, that I have been consistent in use of sizeof() -- same type in both places. Also, the const in your original code is not necessary.
I think, one mistake lies right in the line
qsort(array[0], numThingies, sizeof(array[0]), thingieCmp);
Try
qsort(&array[0], numThingies, sizeof(array[0]), thingieCmp);
or even
qsort(array, numThingies, sizeof(array[0]), thingieCmp);
instead. The compiler won't complain here, as qsort is supposed to take a void* and you pass it a Thingy* which can legally be cast to void* without warning, but you really want qsort to operate on the entire array, which has type Thingy**.
Another thing is: the comparator will be called with pointers to the array slots as arguments, so what you get is actually a Thingy**:
int
thingieCmp(void* a, void* b)
{
Thingie *ia = *((Thingie**)a);
Thingie *ib = *((Thingie**)b);
...
}