scs@adam.mit.edu (Steve Summit) (04/24/91)
In article <frost.672455128@watop> frost@watop.nosc.mil (Richard Frost) writes: > unsigned int **image; > **image = (unsigned int **) malloc(max_el * sizeof(unsigned int *)); > > [This code was] copied from "Answers to Frequently Asked Questions." > [It leads] to the compiler error "Illegal pointer/integer combination" > > Did I miss-copy? What's going on here? There are two problems. The first is that the sample code in the FAQ list does not, at that point, remind you to declare malloc properly. You must use either the line #include <stdlib.h> or extern char *malloc(); depending on whether you have an ANSI or pre-ANSI compiler, respectively. (I can't remember whether this was a deliberate omission in the FAQ list or not. Since the question is "How do I [use malloc to] dynamically allocate a multidimensional array?" and not "How do I use malloc at all?", I may have decided that properly declaring malloc should have been obvious. A later question does mention using <stdlib.h> to declare malloc; this question probably should, too.) The second, larger problem is that the code was miscopied, just a bit, but the difference is crucial. The fragment in the FAQ list saves a line (I hate it when textbook authors compress code to save space, and now I'm doing it) by coalescing the declaration and initialization of the variable `array': int **array = (int **)malloc(nrows * sizeof(int *)); The variable's name is `array'. *array is what it points to, and **array is what what it points to points to :-) . If you want to separate the declaration and assignment, the assignment would look like: array = (int **)malloc(nrows * sizeof(int *)); because it is the (double) pointer variable `array' to which we are first assigning. The next loop for(i = 0; i < nrows; i++) array[i] = (int *)malloc(ncolumns * sizeof(int)); starts filling in the memory that `array' points to (akin to *array), and it's not until we start setting individual array elements (array[i][j] = expr) that we write to the memory that `array' points to points to (i.e. **array). I'll grant that the asymmetric appearance of int **array = <expr>; versus int **array; array = <expr>; is a bit distracting. It's something you just have to get used to. By the way, anyone is free to send me email when there are questions or problems with the FAQ list. (This is not a flame; FAQ list followups have been delightfully infrequent, and Richard's was not out of line.) Steve Summit scs@adam.mit.edu