[ale] Any C Gurus Out There
Joe Knapka
jknapka at kneuro.net
Sun Jan 25 12:41:31 EST 2004
Terry Lee Tucker <terry at esc1.com> writes:
> Hello,
>
> I have a C question. I am experiementing with pointers. I want to be able to
> dynamically allocate a three dimensional array (a table of strings) and I
> want to be able to be able to allocate all the parts of the array using
> pointers. Yes, I know I can use subscripts and yes, I know that would be
> easier to read; but, I just want to be "able" to do it. Here's what I've
> discovvered so far:
> char ***threeD;
> threeD = (char ***) calloc (2, sizeof (char **));
>
> This line works, and allocates space for two rows. I know tthat it works
> because I have used subscripts to allocate, populate and print the contents
> of the array.
>
> I have a pointer row3d defined as:
> char ***row3d;
> row3d = threeD;
> *row3d++ = (char **) calloc (5, sizeof (char *));
> *row3d = (char **) calloc (5, sizeof (char *));
>
> This allocates memory for the two rows and apparently is equivalent to:
> threeD[0] = (char **) calloc (5, sizeof (char *));
> threeD[1] = (char **) calloc (5, sizeof (char *));
>
> This is where the problem starts. I have a pointer defined as:
> char ***row0col;
> row0col = threeD;
>
> I want to use row0col to allocate memory for each column in row 0 and copy a
> string to that address. I thought this would work:
> **row0col = (char *) calloc (20, sizeof (char));
> strcpy (**row0col, "row:0;col:0");
> *(*row0col)++;
According to K&R2, that last line is equivalent to *((*row0col)++),
so you're incrementing *row0col after returning the value stored
there. Is that what you intended?
Rephrasing your code:
Let's see. Assuming your array is in row-major order (that is, the
char**'s pointed at by row0col represent the rows, and the char*'s
pointed at by each of those represent the columns:
row0col is a pointer to a row, so incrementing it takes us
to the next row.
*row0col is a pointer to a column, so incrementing it takes
us to the next column.
**row0col is a char* representing an entry in the array;
incrementing it takes us to the next character in the entry,
which is not very useful right now.
#include <stdio.h>
int main(int argc,char* argv[]) {
// Allocate the rows.
#define NROWS 2
char*** array = (char***)malloc(NROWS*sizeof(char**));
char*** row = array;
int ii,jj;
// Allocate the columns.
#define NCOLS 5
for (ii=0; ii<NROWS; ++ii) {
*row = (char**)malloc(NCOLS*sizeof(char*));
++row; // Easier to see what's going on by incrementing separately, IMO.
}
// Allocate and fill the individual entries.
row = array;
for (ii=0; ii<NROWS; ++ii) {
char** col = *row;
for (jj=0; jj<NCOLS; ++jj) {
*col = (char*)malloc(20);
strcpy(*col,"This is a string");
++col;
}
++row;
}
// Read them back out.
row = array;
for (ii=0; ii<NROWS; ++ii) {
char** col = *row;
for (jj=0; jj<NCOLS; ++jj) {
puts(*col);
++col;
}
++row;
}
}
The code above is typical for me: not as small is it could be, but I
can usually figure out what is was supposed to do years later, with
not too much head-scratching :-)
> But, it doesn't. The first element, column 0, gets copied correctly but I am
> unable to get the pointer to increment correctly so I can allocate a new
> block of memory for the next string in column 1; I have tried many different
> pointer incrementation schemes other that the above. Most don't increment it
> at all. The ones that do, apparently by viewing through gdb, either increment
> the address to the next character in row 0 column 0 or increment the entire
> row.
>
> I can do all of this with subscripts and it works fine. I just can't figure
> out the pointer equivalent to threeD[y][x] and how to increment that with
> pointer arithmetic. If anyone has a clue on this, I would appreciate your
> insight. I'm sure others would as well.
I think you'll find that most experienced C programmers would just
use array syntax for this kind of thing; it's way simpler.
HTH,
-- Joe Knapka
--
(let ((antichrist 'me) (anarchist 'me))) -- the sexp-pistols.
If you really want to get my attention, don't reply to this;
instead, send mail to "jknapka .at. kneuro .dot. net."
More information about the Ale
mailing list