3D array pointer arithmetic

M

Mike H

From the C Faq:

'You can keep the array's contents contiguous, while making later
reallocation of individual rows difficult, with a bit of explicit pointer
arithmetic:
'
' int **array2 = malloc(nrows * sizeof(int *));
' array2[0] = malloc(nrows * ncolumns * sizeof(int));
' for(i = 1; i < nrows; i++)
' array2 = array2[0] + i * ncolumns;

I know this should be obvious, but could someone show an example of how this
would be extended to 3 dimensions?

Thanks,
Mike H.
 
M

Mike H

Arthur J. O'Dwyer said:
From the C Faq: [...]
I know this should be obvious, but could someone show an example of how
this
would be extended to 3 dimensions?

http://groups.google.co.uk/[email protected]
Thanks for the link. This only shows the first example, which I did manage
to work out already. The one I was having trouble with is the second example
that allocates one chunk of memory and then calculates the indexes
afterwards.

Mike H.
 
A

Arthur J. O'Dwyer

Arthur J. O'Dwyer said:
From the C Faq: [...]
I know this should be obvious, but could someone show an example
of how this would be extended to 3 dimensions?

http://groups.google.co.uk/[email protected]

Thanks for the link. This only shows the first example, which I did manage
to work out already. The one I was having trouble with is the second example
that allocates one chunk of memory and then calculates the indexes
afterwards.

Hmm... okay. I think this is correct: [UNTESTED CODE]

int ***array3;
array3 = malloc(ndx * sizeof *array3);
array3[0] = malloc(ndx*ndy * sizeof **array3);
array3[0][0] = malloc(ndx*ndy*ndz * sizeof ***array3);
for (i=1; i < ndx; ++i) {
array3 = array3[0] + i*ndy;
array3[0] = array3[0][0] + i*ndy*ndz;
for (j=0; j < ndy; ++j) {
array3[j] = array3[0] + j*ndz;
}

But why do this, really? ;)

-Arthur
 
E

E. Robert Tisdale

Mike said:
From the C Faq:

'You can keep the array's contents contiguous,
while making later reallocation of individual rows difficult,
with a bit of explicit pointer arithmetic:
'
' int **array2 = malloc(nrows * sizeof(int *));
' array2[0] = malloc(nrows * ncolumns * sizeof(int));
' for(i = 1; i < nrows; i++)
' array2 = array2[0] + i * ncolumns;

I know this should be obvious,
but could someone show an example
of how this would be extended to 3 dimensions?


/* Constructor */
nml_itensor* (nml_it_new)(
nml_extent l, nml_extent m, nml_extent n) {
nml_iscalar*** ppp
= (nml_iscalar***)nml_calloc(4+l, sizeof(nml_iscalar**));
if (NULL != ppp) {
*ppp = NULL; ++ppp;
*((nml_extent*)ppp) = l; ++ppp;
*((nml_extent*)ppp) = m; ++ppp;
*((nml_extent*)ppp) = n; ++ppp;
if ( 0 < l) {
if (0 < m) { /* (0 < l) && (0 < m) */
nml_iscalar** pp
= (nml_iscalar**)nml_calloc(1+l*m, sizeof(nml_iscalar*));
if (NULL != pp) {
*((nml_extent*)pp) = l*m; ++pp;
ppp[0] = pp;
{ nml_offset h = 1;
for (h = 1; h < l; ++h)
ppp[h] = ppp[h-1] + m;
}
if (0 < n) { /* (0 < l) && (0 < m) && (0 < n) */
ppp[0][0] = (nml_iscalar*)nml_iv_new(l*m*n);
if (NULL != ppp[0][0]) {
nml_offset h = 1;
for (h = 1; h < l; ++h)
ppp[h][0] = ppp[h-1][0] + m*n;
for (h = 0; h < l; ++h) {
nml_offset i = 1;
for (i = 1; i < m; ++i)
ppp[h] = ppp[h][i-1] + n;
}
}
else { /* (NULL == ppp[0][0]) */
nml_offset h = 0;
for (h = 0; h < l; ++h) {
nml_offset i = 0;
for (i = 0; i < m; ++i)
ppp[h] = NULL;
}
nml_message(
"In function nml_it_new(nml_extent, nml_extent, nml_extent):\n"
"unable to allocate memory.");
}
}
else { /* (n <= 0) */
nml_offset h = 0;
for (h = 0; h < l; ++h) {
nml_offset i = 0;
for (i = 0; i < m; ++i)
ppp[h] = NULL;
}
}
}
else { /* (NULL == pp) */
nml_offset h = 0;
for (h = 0; h < l; ++h)
ppp[h] = NULL;
nml_message(
"In function nml_it_new(nml_extent, nml_extent, nml_extent):\n"
"unable to allocate memory.");
}
}
else { /* (m <= 0) */
nml_offset h = 0;
for (h = 0; l < m; ++h)
ppp[h] = NULL;
}
}
}
else { /* (NULL == ppp) */
nml_message(
"In function nml_it_new(nml_extent, nml_extent, nml_extent):\n"
"unable to allocate memory.");
}
return ppp;
}

/* Destructor */
void (nml_it_delete)(nml_itensor* pT) {
if (NULL != pT) {
if (NULL != pT[0]) {
nml_iv_delete(pT[0][0]);
nml_free(pT[0] - 1);
}
nml_free(pT - 4);
}
}
 
M

Mike H

Arthur J. O'Dwyer said:
Arthur J. O'Dwyer said:
[...]
I know this should be obvious, but could someone show an example
of how this would be extended to 3 dimensions?

http://groups.google.co.uk/[email protected]

Thanks for the link. This only shows the first example, which I did
manage
to work out already. The one I was having trouble with is the second
example
that allocates one chunk of memory and then calculates the indexes
afterwards.

Hmm... okay. I think this is correct: [UNTESTED CODE]

int ***array3;
array3 = malloc(ndx * sizeof *array3);
array3[0] = malloc(ndx*ndy * sizeof **array3);
array3[0][0] = malloc(ndx*ndy*ndz * sizeof ***array3);
for (i=1; i < ndx; ++i) {
array3 = array3[0] + i*ndy;
array3[0] = array3[0][0] + i*ndy*ndz;
for (j=0; j < ndy; ++j) {
array3[j] = array3[0] + j*ndz;
}

But why do this, really? ;)


Well, if for nothing else, just so I know how :)

Thanks Arthur, this doesn't seem to work either. I found a sample at
snippets.com that uses this method, but in a recursive function that allows
any number of dims/elements. It's a little harder to follow the resursive
structure, I'll have to study it a little more.

Thanks,
Mike H.
 
A

Arthur J. O'Dwyer

Arthur J. O'Dwyer said:
"Arthur J. O'Dwyer" <[email protected]> wrote...

Hmm... okay. I think this is correct: [UNTESTED CODE]

int ***array3;
array3 = malloc(ndx * sizeof *array3);
array3[0] = malloc(ndx*ndy * sizeof **array3);
array3[0][0] = malloc(ndx*ndy*ndz * sizeof ***array3);
for (i=1; i < ndx; ++i) {
array3 = array3[0] + i*ndy;
array3[0] = array3[0][0] + i*ndy*ndz;
for (j=0; j < ndy; ++j) {
array3[j] = array3[0] + j*ndz;
}

But why do this, really? ;)


Well, if for nothing else, just so I know how :)

Thanks Arthur, this doesn't seem to work either.


Right. Tested and found the bugs. One obvious extraneous '{', and
one off-by-one error --- some of the pointers weren't getting initialized.

int ***array3;
int i,j,k;
array3 = malloc(ndx * sizeof *array3);
array3[0] = malloc(ndx*ndy * sizeof **array3);
array3[0][0] = malloc(ndx*ndy*ndz * sizeof ***array3);
if (!array3 || !array3[0] || !array3[0][0])
do_error("I don't have enough memory to allocate the array!");
for (i=0; i < ndx; ++i) {
array3 = array3[0] + i*ndy;
array3[0] = array3[0][0] + i*ndy*ndz;
for (j=1; j < ndy; ++j)
array3[j] = array3[0] + j*ndz;
}

I repeat, you really don't want to do this for anything more than
two-dimensional arrays, and probably not even then. It's really icky.
(See Tisdale's post for a perfect example.)

-Arthur
 
M

Mike H

Right. Tested and found the bugs. One obvious extraneous '{', and
one off-by-one error --- some of the pointers weren't getting initialized.

int ***array3;
int i,j,k;
array3 = malloc(ndx * sizeof *array3);
array3[0] = malloc(ndx*ndy * sizeof **array3);
array3[0][0] = malloc(ndx*ndy*ndz * sizeof ***array3);
if (!array3 || !array3[0] || !array3[0][0])
do_error("I don't have enough memory to allocate the array!");
for (i=0; i < ndx; ++i) {
array3 = array3[0] + i*ndy;
array3[0] = array3[0][0] + i*ndy*ndz;
for (j=1; j < ndy; ++j)
array3[j] = array3[0] + j*ndz;
}

I repeat, you really don't want to do this for anything more than
two-dimensional arrays, and probably not even then. It's really icky.

I mainly wanted to get a better understanding of the different methods. I
can certainly see the pros and cons in each.
(See Tisdale's post for a perfect example.)
:) No argument there :)


Thanks, this works well. After studying your example. I was able to better
understand the other code I got from snippet.com. A very clever piece of
work.

Thanks again,
Mike H.
 
M

Mike H

E. Robert Tisdale said:
Mike said:
From the C Faq:

'You can keep the array's contents contiguous, while making later
reallocation of individual rows difficult,
with a bit of explicit pointer arithmetic:
'
' int **array2 = malloc(nrows * sizeof(int *));
' array2[0] = malloc(nrows * ncolumns * sizeof(int));
' for(i = 1; i < nrows; i++)
' array2 = array2[0] + i * ncolumns;

I know this should be obvious,
but could someone show an example
of how this would be extended to 3 dimensions?


/* Constructor */
nml_itensor* (nml_it_new)(
nml_extent l, nml_extent m, nml_extent n) {
nml_iscalar*** ppp



Thanks for posting the code, even though I don't really understand it :)

Mike H.
 
J

John Smith

Mike said:
Thanks for posting the code, even though I don't really understand it :)

Mike H.
Welcome to the club.
If you hang around here long enough you will learn that ERT
is a notorious provocateur. As is usually the case, his code is:

off topic in c.l.c (since it's not C)
not intended to be helpful to someone learning C
an exercise in self-congratulation


JS
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top