multidimensional very large array - arraylist

Hi i want to use multidimensional very large array. I tried following code. It compiles but when i execute it it gives me segmentation fault error.
'int NT = 35; int NX = 25; int NY = 25; int NZ = 25;
double dt = 0.1; double dx = 0.5; double dy = 0.5; double dz = 0.5;
double PosT[NT];
double PosX[NX]; double PosY[NY]; double PosZ[NZ];
for(int i=0;i<NT;i++)
PosT[i] = i*dt+dt;
for(int i=0; i<NX;i++)
PosX[i] = dx*i;
for(int i=0; i<NY;i++)
PosY[i] = dy*i;
for(int i=0; i<NZ;i++)
PosZ[i] = dz*i;
double* b_x=(double*)malloc(NX*NY*NZ*sizeof(double));
double* b_y=(double*)malloc(NX*NY*NZ*sizeof(double));
double** B=(double**)malloc(NX*NY*NZ*NT*sizeof(double*));
if(b_x==NULL||b_y==NULL){
cout<<"Malloc space error!"<<endl;
return 0;
}
for(int ix=0;ix<NX;ix++){
for(int iy=0;iy<NY;iy++){
for(int iz=0;iz<NZ;iz++){
int position=ix*NY*NZ+iy*NZ+iz;
b_x[position] =0.;
b_y[position] =0.;
}
}
}'
but when i work in below part then i got segmentation error, my codes next part is following lines which include 2d arrays. and this 2d array is very large ,
perhaps due to this i am getting segmentation error
'if(B==NULL){
cout<<"Malloc space error!"<<endl;
return 0;
}
cout<<"work"<<endl;
for(int ix=0;ix<NX;ix++){
for(int iy=0;iy<NY;iy++){
for(int iz=0;iz<NZ;iz++){
int position=ix*NY*NZ+iy*NZ+iz;
for(int it=0;it<NT;it++){
B[position][it]=0.;
}
}
}
}
cout<<"not working"<<endl;'
so code between work and not working has problem which causes segmentation error. Any solutions for this.

int NT = 35; int NX = 25; int NY = 25; int NZ = 25;
For simplicity, let's change all of these to NT=NX=NY=NZ=2. This line:
double** B=(double**)malloc(NX*NY*NZ*NT*sizeof(double*));
would then allocate space for 16 pointers. On the first iteration through the loops, this line:
B[position][it]=0.;
would be equivalent to:
double *tmp = B[0]; // Load uninitialized pointer from B[0]
tmp[0] = 0.0; // Dereference uninitialized pointer to store something.
It shouldn't be at all surprising that this code results in a SIGSEGV.
What you probably meant:
double *B = malloc(NX*NY*NZ*NT*sizeof(double));
for(int ix = 0; ix < NX; ix++) {
for(int iy = 0; iy < NY; iy++) {
for(int iz = 0; iz < NZ; iz++) {
for(int it = 0; it < NT; it++) {
int position = NT * (NZ * (NY * ix + iy) + iz) + it;
B[position] = 0.0;
}
}
}
}

Related

Populating table causes unexpected results

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");
}

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.

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.)

From char* array to two dimentional array and back algorithm goes wrong

I think my algorithm has flawed logic somewhere. Calling the two functions should return the same image however it doesn't! Can anyone see where my logic goes wrong?
These functions are used on PNG-images, I have found that they store colors as follows: ALPHA, RED, GREEN, BLUE. Repeatingly for the whole image. "pixels" is just a long array of those values (like a list).
My intent is to do a lowpass filter on the image, which is a lot easier logic if you instead use a two dimentional array / matrix of the image.
// loading pixels
UIImage *image = imageView.image;
CGImageRef imageRef = image.CGImage;
NSData *data = (NSData *)CGDataProviderCopyData(CGImageGetDataProvider(imageRef));
char *pixels = (char *)[data bytes];
// editing image
char** matrix = [self mallocMatrix:pixels withWidth:CGImageGetWidth(imageRef) andHeight:CGImageGetHeight(imageRef)];
char* newPixels = [self mallocMatrixToList:matrix withWidth:CGImageGetWidth(imageRef) andHeight:CGImageGetHeight(imageRef)];
pixels = newPixels;
and the functions looks like this:
- (char**)mallocMatrix:(char*)pixels withWidth:(int)width andHeight:(int)height {
char** matrix = malloc(sizeof(char*)*height);
int c = 0;
for (int h=0; h < height; h++) {
matrix[h] = malloc(sizeof(char)*width*4);
for (int w=0; w < (width*4); w++) {
matrix[h][w] = pixels[c];
c++;
}
}
return matrix;
}
- (char*)mallocMatrixToList:(char**)matrix withWidth:(int)width andHeight:(int)height {
char* pixels = malloc(sizeof(char)*height*width*4);
int c = 0;
for (int h=0; h < height; h++) {
for (int w=0; w < (width*4); w++) {
pixels[c] = matrix[h][w];
c++;
}
}
return pixels;
}
Edit: Fixed the malloc as posters pointed out. Simplified the algorithm a bit.
I have not tested your code but it appears you are allocating the incorrect size for your matrix and low pass filter as well as not moving to the next pixel correctly.
- (char**) mallocMatrix:(char*)pixels withWidth:(int)width andHeight:(int)height {
//When using Objective-C do not cast malloc (only do so with Objective-C++)
char** matrix = malloc(sizeof(char*)*height);
for (int h=0; h < height; h++) {
//Each row needs to malloc the sizeof(char) not char *
matrix[h] = malloc(sizeof(char)*width*4);
for (int w=0; w < width; w++) {
// Varje pixel har ARGB
for (int i=0; i < 4; i++) {
matrix[h][w+i] = pixels[h*w+i];
}
}
}
return matrix;
}
- (char*) mallocLowPassFilter:(char**)matrix withWidth:(int)width andHeight:(int)height
{
//Same as before only malloc sizeof(char)
char* pixels = malloc(sizeof(char)*height*width*4);
for (int h=0; h < height; h++) {
for (int w=0; w < width; w++) {
// Varje pixel har ARGB
for (int i=0; i < 4; i++) {
// TODO: Lowpass here
pixels[h*w+i] = matrix[h][w+i];
}
}
}
return pixels;
}
Note: This code, as you know, is limited to ARGB images. If you would like to support more image formats there are additional functions available to get more information about your image such as CGImageGetColorSpace to find the pixel format (ARGB, RGBA, RGB, etc...), and CGImageGetBytesPerRow to get the number of bytes per row (you wouldn't have to multiply width by channels per pixel).