Populating table causes unexpected results - objective-c

I am totally stumped. I have been debugging this for hours. I am allocating a table of 100 UInt32s by 100. I am loading a table of values and writing them to the 2D array. For some bizarre reason when I get to row 67, column 0 the writes appear to wrap back around to row 0 element 0.
I have rewritten it to allocate a list of arrays rather than a single malloc. Same exact behavior. I have tried doing math for the index: _map[row * 100 + column] instead of _map[i,j] and that leads to other strange behavior. I was thinking maybe something is overflowing, but I can't see how since the data is so small. Obviously I am doing something stupid but I just... can't.. see it.
Code snippet:
_map = malloc(100 * 100 * sizeof(UInt32));
int i = 0;
for (i=0; i <_columns; i++)
{
columnList = [[lineList objectAtIndex:i] componentsSeparatedByString:#","];
int j = 0;
for (j=0; j < _rows; j++)
{
UInt32 dataInt = atoi([[columnList objectAtIndex:j] UTF8String]);
// Convert the data
NSDictionary* tDict = [fileMap objectForKey:[NSString stringWithFormat:#"%i", dataInt]];
int newVal = [[tDict objectForKey:#"convert"] integerValue];
_map[i,j] = (UInt32)newVal;
UInt32 y = _map[i,j];
// This trips at row 67 element 0
if (_map[0,0] != 1)
printf("Here\n");
}
}
Any help would be absolutely most awesomely appreciated.
As I mention below, this code gives the same problem in that it corrupts the first line. As if every row is the same row:
int** testMap = malloc(100 * 100 * sizeof(int));
int data = 0;
for (int i = 0; i<100; i++)
{
for (int j = 0; j < 100; j++)
{
testMap[i, j] = data;
data++;
printf("(%i, %i)", i,j);
}
printf ("\n");
}

Related

Dividing an array into separate arrays of four elements plus the reminder

I'm trying to divide an array into individual arrays of four elements, where the last array will contain the reminder. For example, if that main array's length property will be ten, three subarrays will be created - two consisting of four elements, and one of two elements.
The code I have right now looks like the following:
NSMutableArray *mainMutableArray = [NSMutableArray arrayWithObjects:#"First", #"Second", #"Third", #"Fourth", #"Fifth", #"Sixth", #"Seventh", #"Eighth", nil];
NSMutableArray *mutableArrayOfSubarrays = [NSMutableArray array];
int length = mainMutableArray.count / 4;
int location = 0;
for (int i = 0; i < length; i++)
{
[mutableArrayOfSubarrays addObject:[mainMutableArray subarrayWithRange:NSMakeRange(location, 4)]];
location += 4;
}
This of course works only when the reminder is equal to 0.
Any help would be greatly appreciated.
Ok, here we go:
int length = mainMutableArray.count;
for (int location = 0; location < length; location+=4)
{
unsigned int Size=length-location;
if (Size>4) Size=4;
[mutableArrayOfSubarrays addObject:[mainMutableArray subarrayWithRange:NSMakeRange(location, Size)]];
}
If you use a while loop, you can make the condition describe what you are actually trying to do:
NSUInteger length = [mainMutableArray count];
NSUInteger location = 0;
// Until the location is less than four away from the end
while( location <= (length - 4) ){
[mutableArrayOfSubarrays addObject:[mainMutableArray subarrayWithRange:NSMakeRange(location, 4)]];
location += 4;
}
// Pick up the remainder, if any
if( location != length ){
[mutableArrayOfSubarrays addObject:[mainMutableArray subarrayWithRange:NSMakeRange(location, length-location)]];
}
Loop from length*4 to mainMutableArray.count to get the remainder of the array.

Conditional assigning a value to int variable in loop (optimization)

Let's say that we have two dimensional array of bools which represent map of simple game. Every cell of array can be set to true if cell is occupied by some game's object (else false).
We want to update map in loop regarding to objects' behaviour. Let's say (because of some reasons) we are not able to update only some regions of the map, we have to iterate every cell in the array and negate it's value if object has changed its position.
We know that in every array's update there are only few changes but array is huge. And now comes the question.
What is more optimal.
(1) This:
for (int i = 0; i < Rows; i++)
for (int j = 0; j < Cols; j++)
{
bool newValue = update(i,j);
arr[i,j] = arr[i,j] != newValue ? newValue : arr[i,j];
}
(2) this:
for (int i = 0; i < Rows; i++)
for (int j = 0; j < Cols; j++)
{
bool newValue = update(i,j);
if(newValue != arr[i,j])
arr[i,j] = newValue;
}
(3) or maybe this:
for (int i = 0; i < Rows; i++)
for (int j = 0; j < Cols; j++)
{
arr[i,j] = update(i,j);
}
I think (1) is worst solution here. So (2) vs (3).
No 3. There is no reason to write the code like you did in #2. You can remove the if without any problems.

The scripted value is neither an array nor a pointer

So I am trying to allocate memory for a 2D array of ints such that I can reference it outside of the loop in which the size is determined. (I have a scope issue because the size of the array isn't fixed.)
So this was the proposed solution, but I am getting the error "The scripted value is neither an array nor a pointer". Anyone know what I am doing wrong?
//M and m are just 2 int numbers
int X = self.create2dArray(M,m);
for(int kk = 0; kk < M; kk++)
{
for (int kk1 = 0; kk1 < m; kk1++)
{
//small "x" is an NSMutableArray of NSNumbers. So I am just running the 2 for loops to fill the whole 2D array
X[kk][kk1] = [[x objectAtIndex: (kk + kk1 * J)] intValue]; //ERROR Line
}
}
//outside of Main
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;
}
I believe that first line should start with int** X instead of int X
Okay, so your problem may most likely lie within your manually allocating of the memory for the integers. My proposed solution is to just fill it up with random "filler" numbers, for instance: 0. By doing so, you don't risk messing up the allocation process. In addition, it's much easier and it works given you'll be filling it up with integers later on. Hope this helped!

Using malloc to create a 2d C style array of my class

(Edit: put possible solution at end)
I'm a C/C++ programmer who is learning Objective C to develop iPhone apps. The programs that I will be writing will deal with large 2d arrays of objects. I've read about using NSArray's of NSArray's and have some working code, but I'm trying to understand how to use C style arrays to save overhead and to learn what you can and can't do.
In this fragment MapClass only contains two properties, int x and int y. I have the following code fragment working with a statically defined array of 10x10.
MapClass *arr[10][10];
arr[2][3] = [[MapClass alloc] init];
arr[2][3].x = 2;
arr[2][3].y = 3;
NSLog(#"The location is %i %i", arr[2][3].x, arr[2][3].y);
// Output: "The location is 2 3"
This is an example of doing it with a one dimensional array and calculating where the cell is based on the X and Y:
MapClass **arr = (MapClass**) malloc(10 * 10 * sizeof(MapClass *));
arr[3 * 10 + 2] = [[MapClass alloc] init];
arr[3*10 + 2].x = 2;
arr[3*10 + 2].y = 3;
NSLog(#"The location is %i %i", arr[3*10 + 2].x, arr[3*10 + 2].y);
// Output: "The location is 2 3"
My question is this: How can I malloc my array as a two dimensional array so that I can use arr[2][3] style notation to access it?
Everything I'm trying is generating various errors such as "Subscript requires the size of [your class], which is not constant in non-fragile ABI".
Can anyone give me a snippit on how to do this? I've been reading and experimenting and can't figure it out. Does my one dimensional array example do anything wrong?
Answer?
After fooling around with xzgyb's answer, I have the following block working. Anything wrong with it? Thanks!
int dimX = 20;
int dimY = 35;
MapClass ***arr = (MapClass***) malloc( dimX * sizeof(MapClass **));
for (int x = 0; x < dimX; ++x)
{
arr[x] = (MapClass **) malloc( dimY * sizeof(MapClass*));
}
for (int x = 0; x < dimX; ++x)
{
for (int y = 0; y < dimY; ++y)
{
arr[x][y] = [[MapClass alloc] init];
arr[x][y].x = x;
arr[x][y].y = y;
}
}
for (int x = 0; x < dimX; ++x)
{
for (int y = 0; y < dimY; ++y)
{
NSLog(#"%i %i is %i %i", x, y, arr[x][y].x, arr[x][y].y);
}
}
// Cleanup
for (int x = 0; x < dimX; ++x) {
for (int y = 0; y < dimY; ++y) {
[arr[x][y] release];
}
}
for (int x = 0; x < dimX; ++x)
{
free(arr[x]);
}
free(arr);
Try the followed code:
MapClass ***arr = (MapClass***) malloc(10 * 10 * sizeof(MapClass *));
for ( int row = 0; row < 10; ++row ) {
arr[ row ] = (MapClass **)&arr[ row * 10 ];
}
arr[0][1] = [[MapClass alloc] init];
arr[1][2] = [[MapClass alloc] init];
Tested and it works fine using NSMutableString class and a variety of string methods.
I'd probably recommend using the standard message sending brackets than using the newer dot operator syntax just to simplify to the compiler what you are actually trying to accomplish.
The sizeof(ClassName ) should be the same as sizeof([ClassName class]) (and int or id for that matter) if I understand your meaning. The code you posted should not give an error like that as all pointers will be the same size. Now if you tried something like sizeof(*someInstanceOfAClass) then you're running into some issues because you're attempting to malloc enough memory to fit 10*10*(the actual size of your object) which is not what you're intending to do. (And sounds like what your warning is intended for.)

Array giving EXC_BAD_ACCESS in for loop

I have a C array defined in my method as:
int c = 4;
int r = 5;
keysArray[c][r];
I have this for loop, which works, populating the keysArray as expected.
for (int row = 0; row < r; row++) {
for (int column = 0; column < c; column++){
keysArray[column][row] = [anotherArray objectAtIndex:0];
NSLog(#"array1 %#",keysArray[column][row]);
[anotherArray removeObjectAtIndex:0];
}
}
Then in a for loop underneath, featuring exactly the same looping counter structure, when i try to NSLog the array, it gives an EXC_BAD_ACCESS.
for (int row = 0; row < r; row++){
for (int column = 0; column < c; column++) {
NSLog(#"array2: %#",keysArray[column][row]); //EXC_BAD_ACCESS here
}
}
What would cause this to happen, given that the keysArray is defined in the method body, outside of both sets of loops?
Are the contents of anotherArray retained by some other object? If not, they do not exist anymore in the second loop. WTH are you using a C array to store Objective-C objects anyway?
int c = 4;
int r = 5;
NSMutableArray *keysArray = [[NSMutableArray alloc] initWithCapacity:c];
for (int column = 0; column < c; column++) {
[keysArray addObject:[NSMutableArray arrayWithCapacity:r]];
for (int row = 0; row < r; row++) {
[[keysArray objectAtIndex:column] addObject:[anotherArray objectAtIndex:0]];
[anotherArray removeObjectAtIndex:0];
}
}
for (int row = 0; row < r; row++){
for (int column = 0; column < c; column++) {
NSLog(#"array2: %#", [[keysArray objectAtIndex:column] objectAtIndex:row]);
}
}
You need to retain the objects held in your C array. Unlikes an NS*Array, a C array does not retain on adding to the array.
However, for a no-holes 2D array like that, I'd just use a single NSMutableArray. Any N-dimensional array can be represented as a line-- as a one dimensional array-- with simple math.
Namely, to determine the index of an object at (X,Y), use (Y * width) + X).
The only caveat is that NS*Array does not support "holes". You will need to fill the array row by row. That is, for a 3x4 (3 wide, 4 tall) array, you would fill it in the order 0,0, 1,0, 2,0, 0,1, 1,1, etc...
Obviously, insert and remove operations will mess up your 2D representation (but they would in an NSMutableArray of NSMutableArrays, too).
Alternatively, use NSPointerArray as it can have holes.
Could this be the problem :
[anotherArray removeObjectAtIndex:0];
try
keysArray[column][row] = [[anotherArray objectAtIndex:0] retain];
although if I were you I would use NSMutableArray of NSMutableArray instead