kevin@crash.cts.com (Kevin Hill) (01/23/91)
I am still having problems with the malloc use in allocating memory for a two dimensional array. I thank everyone that has been attempting to help me with this. As of now, these are the variables outside of the function to follow: int **track; int **map; char *bigmap; int cursor,x1 = 0,y1 = 0,gx,gy; WindowPtr thewind,thewind1; WindowRecord windowmemory,windowmemory1; BitMap themap1,store; char iconmap[128]; Rect oldbox; int **track; int **map; char *bigmap; Initialize() { int x,y; gx = gy = 0; store.rowBytes = 4; SetRect(&store.bounds,0,0,32,32); if ( (bigmap = (char *)( malloc( (unsigned)(100 * 100 * 128)) )) == NULL) ExitToShell(); track = (int **)malloc( (unsigned)(100 * sizeof(int *)) ); track[0] = (int *)malloc( (unsigned)( 100 * 100 * sizeof(int)) ); if (track[0] == NULL) ExitToShell(); map = (int **)malloc( (unsigned)(100 * sizeof(int *)) ); map[0] = (int *)malloc( (unsigned)(100 * 100 * sizeof(int)) ); if (map[0] == NULL) ExitToShell(); for (x = 1; x < 100; x++) { track[x] = track[x-1] + (100 * sizeof(int)); map[x] = map[x-1] + (100 * sizeof(int)); for (y = 0; y < 100; y++) { map[x][y] = -1; track[x][y] = -1; } } } } So that is the extent of the stuff that I have attempted. Now the problem is that when the computer allocates using malloc, it returns very low address' or very high address'. The low ones, which are the most common are standard, and they are 0x000012A, is that an address to a master pointer list, and I need to dereference that also? Also, when I complete the malloc to issue the 100 pointers for either of them, if I use the debugger to find the address of track[0], track[1], it is still low. Is malloc buggy, or am I. I am betting that I am the one that is buggy! Also, yes I did read the FAW sheet that Steve Summit sent me, (FAQ not FAW, sorry) and question #20 is the only one that applies to my question, and if you look at the code above, you will see that I did follow it, and I think that I understand it. For example, when track is allocated by the malloc statement, I am giving memory space for the pointers that will point to the integers that I am trying to store. Then after that, I put into track[0] the beginning of the space of the actual 100x100 space for the integers of the two dimensional array. The for loop below sets up the pointers to point to the correct places in memory, and initializes the values of the pointers. So, far, the machine crashes at the malloc points, sometimes. Or always, when it gets to the actual initialization of the array. Yes, I know that if I have the wrong address' I am overwriting areas that the system could be using, but malloc should be sending back to me the correct address' and I believe that I am using the right coding to create the two-dimensional arrays that I am using. Thanks.
jdb@reef.cis.ufl.edu (Brian K. W. Hook) (01/23/91)
In article <7156@crash.cts.com> kevin@crash.cts.com (Kevin Hill) writes: > > I am still having problems with the malloc use in allocating memory >for a two dimensional array. I thank everyone that has been attempting >to help me with this. I don't know exactly what system you are writing on, but I assume that it is PC compatible. Actually, some code looks like Mac, but either way it is not very relevant. Have you tried using a SINGLE pointer instead of two? Or are you doing something that I am not aware of. For example, I wrote a windowing library that looks much like some of that code you are using (which actually looks quite a lot like the MetaWINDOWS library). typedef struct _window { int width, height; BYTE *oldImage; ... } WINDOW; While it is more intuitive to declare an array of pointers for a rectangular region I have found that the following works REAL well and adds some simplicity. void createWin ( WINDOW *wnd /* Whatever else needs to be passed */ ) { ... wnd->oldImage=(BYTE *)(malloc(wnd->width*wnd->height)+1); // I add 1 // just in case ... } This assumes that the WINDOW doesn't cast a shadow and that the area behind is definable as a BYTE (8 bits, as far as I am concerned...a 256 color bit map) for each discreate location behind the WINDOW (i.e. pixel). Now, back to the two dimensional array. How about indicing each pointer that you need using a little bit of pointer arithmetic. The equation should be: BYTE *rowToFind=wnd->oldImage+(wnd->width*row+column); This assumes that "row" and "column" is the starting pixel for the address you wish to find. Since you are looking for a pointer per row (thus simulating a two dimensional array) "column" would be 0. Then you would just grab wnd->width amount of BYTEs to get that entire line. Hope this helped, Brian
smbrush@helios.lerc.nasa.gov (Andrew Brush (Sverdrup)) (01/29/91)
In response to Kevin Hill's question in 7156@crash.cts.com, I compiled and ran the following small program on my PC using MSC5.1 and on VMS using VAX C v3.0 with no problems. #include <stdlib.h> #include <stdio.h> void main(void); void main(void){ int **track; int ix, iy; track = (int **)malloc( (unsigned)(100*sizeof(int *))); track[0] = (int *)malloc( (unsigned)(100*sizeof(int))); for (ix=1;ix<100;ix++){ track[ix] = track[ix-1] + (100*sizeof(int)); printf("%p\n",track[ix]); } for (ix=0;ix<100;ix++){ for (iy=0;iy<100;iy++){ track[ix][iy] = ix*iy; printf("%d\n",track[ix][iy]); } } } This is slightly different from his program fragment: int **track; int **map; char *bigmap; int cursor,x1 = 0,y1 = 0,gx,gy; WindowPtr thewind,thewind1; WindowRecord windowmemory,windowmemory1; BitMap themap1,store; char iconmap[128]; Rect oldbox; int **track; int **map; char *bigmap; Initialize() { int x,y; gx = gy = 0; store.rowBytes = 4; SetRect(&store.bounds,0,0,32,32); if ( (bigmap = (char *)( malloc( (unsigned)(100 * 100 * 128)) )) == NULL) ExitToShell(); track = (int **)malloc( (unsigned)(100 * sizeof(int *)) ); track[0] = (int *)malloc( (unsigned)( 100 * 100 * sizeof(int)) ); if (track[0] == NULL) ExitToShell(); map = (int **)malloc( (unsigned)(100 * sizeof(int *)) ); map[0] = (int *)malloc( (unsigned)(100 * 100 * sizeof(int)) ); if (map[0] == NULL) ExitToShell(); for (x = 1; x < 100; x++) { track[x] = track[x-1] + (100 * sizeof(int)); map[x] = map[x-1] + (100 * sizeof(int)); for (y = 0; y < 100; y++) { map[x][y] = -1; track[x][y] = -1; } } } } 1) For some reason, he shows declarations for his pointer variables twice. 2) His attempt to initialize track and map while also organizing their memory results in failure to initialize row [0] of them. 3) I'm not using any error checking on malloc, although i should. Kevin isn't using error checking when allocating memory for track or map. Possibly, the request for 1,280,000 bytes (or more, depending on sizeof(char) ) for bigmap uses up his available memory, resulting in track==NULL (which is untested), so an attempt to do: track[0]= .... is an attempt to assign a value to something with the address of NULL. Andy Brush [Sverdrup Technology] 216-826-6770 SMBRUSH@MARS.lerc.nasa.gov