eychaner@suncub.bbso.caltech.edu (Amateurgrammer) (03/04/91)
Warm up those flame guns! It's time for Another Novice Question! I know this is partly covered in the FAQ, but it didn't seem to have quite the answer I want. I know that if I malloc a chunk of memory, like so: char *bigmemory; bigmemory = (char *) malloc (OODLES_O_BYTES); I can access the chunk of memory as though it were an array, like so: bigmemory [RIGHT_HERE] = SOME_CHARACTER; (I hope I have this right. This should decompose to: *(bigmemory + RIGHT_HERE) = SOME_CHARACTER; shouldn't it?) So how can I access it as a 2D array, like so: bigmemory [RIGHT_HERE][RIGHT_NOW] = SOME_CHARACTER; I know I could use, for example: *(bigmemory + RIGHT_HERE * SIZEOF_RIGHTNOW + RIGHT_NOW) = SOME_CHARACTER; but all my previous code (which uses the 2D array) would then have to be changed. And it looks much nicer (when RIGHT_HERE and RIGHT_NOW are big, nasty expressions) in 2D array format. And don't flame me for "writing bad code"; it was written during a kinder, gentler period. I'm doing the best that I can, learning as I go along. -Glenn :-) Glenn Eychaner - Big Bear Solar Observatory - eychaner@suncub.bbso.caltech.edu "You Have the Right to Remain DEAD." -The Simpsons
dave@cs.arizona.edu (Dave P. Schaumann) (03/04/91)
In article <1991Mar3.172942.3116@nntp-server.caltech.edu> eychaner@suncub.bbso.caltech.edu writes: >Warm up those flame guns! It's time for Another Novice Question! > >I know this is partly covered in the FAQ, but it didn't seem to have quite >the answer I want. >[...] > bigmemory = (char *) malloc (OODLES_O_BYTES); >I can access the chunk of memory as though it were an array, like so: > bigmemory [RIGHT_HERE] = SOME_CHARACTER; >[becomes] > *(bigmemory + RIGHT_HERE) = SOME_CHARACTER; Right. > bigmemory [RIGHT_HERE][RIGHT_NOW] = SOME_CHARACTER; /* This requires that OODLES_O_BYTES is divisible by NUMBER_OF_ENTRIES_WANTED. */ char **two_d = malloc(NUMBER_OF_ENTRIES_WANTED * sizeof(char *)) for( i = 0 ; i < NUMBER_OF_ENTRIES_WANTED ; i++ ) two_d[i] = &bigmemory[ i * OODLES_O_BYTES / NUMBER_OF_ENTRIES_WANTED ] Now you can say two_d[RIGHT_HERE][RIGHT_NOW] = SOME_CHARACTER Provided I haven't made an Incredibly Stupid Mistake (TM), you should be able to modify this to your needs. -- Dave Schaumann dave@cs.arizona.edu 'Dog Gang'! Where do they get off calling us the 'Dog Gang'? I'm beginning to think the party's over. I'm beginning to think maybe we don't need a dog. Or maybe we need a *new* dog. Or maybe we need a *cat*! - Amazing Stories
torek@elf.ee.lbl.gov (Chris Torek) (03/04/91)
In article <1991Mar3.172942.3116@nntp-server.caltech.edu> eychaner@suncub.bbso.caltech.edu writes: >Warm up those flame guns! It's time for Another Novice Question! Ah, but you at least checked the FAQ and thought a bit before you posted :-) >[I can malloc a `1D array' but] how can I access it as a 2D array, like so: > bigmemory [RIGHT_HERE][RIGHT_NOW] = SOME_CHARACTER; >I know I could use, for example: > *(bigmemory + RIGHT_HERE * SIZEOF_RIGHTNOW + RIGHT_NOW) = SOME_CHARACTER; >but all my previous code (which uses the 2D array) would then have to be >changed. And it looks much nicer (when RIGHT_HERE and RIGHT_NOW are big, >nasty expressions) in 2D array format. Presumably `SIZEOF_RIGHTNOW' is an integer constant and will never change (i.e., is fixed by the design; the algorithm only works on M-by-31 arrays or some such). For the following discussion, let us say it is a `#define N 31'. (It must in fact be some integer constant in the `previous code' since C arrays must have fixed, integral sizes.) Then: char (*p)[N]; declares p as a `pointer to array 31 of char'. This means that p can point to an `array 31 of char'; but moreover, just as `char *bigmemory' can point to more than one of its base type (char), so too `p' can point to more than one of its base type (array 31 of char). If you want M such arrays, all contiguous: p = (char (*)[N])malloc(M * sizeof *p); if (p == NULL) die("out of memory"); (or `p = (char (*)[N])malloc(M * sizeof(char [N]));' or ...malloc(M * N * sizeof(char)) or malloc(M * N * 1) or malloc(M * N); these are all equivalent). Once you have done this: p[i][j] (where 0 <= i < M and 0 <= j < N) is an individual `char'. This works because p[i] names the i'th object to which p points, i.e., the i'th `array 31 of char'. This array appears in a value context, so The Rule applies; we take the corresponding `pointer to char' (which points to the first character in the i'th `array 31 of char') and name its j'th object. Now, if the reason you are changing the code is that N is *not* a fixed integer constant, all of this goes out the window. Someone else has posted a row-vector solution (and others appear in the FAQ), so I will stop here. -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov