[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