473,387 Members | 1,481 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Accessing via a pointer to 2d array.

Hi all,

I have a 2d float array to which I have declared a pointer thus:

float Matrix[4][3] = {/* snipped initialisation */ };
float (*StoredMatrix)[4][3];
So as to create a copy in a program "registry" of my own devising.

I copy the Marix array as follows:

StoredMatrix = malloc(sizeof Matrix);
if(!StoredMatrix)
{
memcpy((void*)StoredMatrix, (void*)Matrix, sizeof Matrix);
}
else
{ /* take action */ }

My question is whether this is legal, and if so whether it is dangerous?
So far, the copied version dereferences OK using the [] operators - eg
using *StoredMatrix[2][1] etc. I'm not finding K&R helpful on the subject.

Any advice appreciated.
TheS

Nov 13 '05 #1
14 6304
Thes <no*@ctually.myaddress.com> scribbled the following:
Hi all, I have a 2d float array to which I have declared a pointer thus: float Matrix[4][3] = {/* snipped initialisation */ };
float (*StoredMatrix)[4][3];
So as to create a copy in a program "registry" of my own devising. I copy the Marix array as follows: StoredMatrix = malloc(sizeof Matrix);
if(!StoredMatrix)
Surely you mean if (StoredMatrix), or better yet,
if (StoredMatrix != NULL) here? The way you've written here is asking
for trouble.
{
memcpy((void*)StoredMatrix, (void*)Matrix, sizeof Matrix);
}
else
{ /* take action */ } My question is whether this is legal, and if so whether it is dangerous?
So far, the copied version dereferences OK using the [] operators - eg
using *StoredMatrix[2][1] etc. I'm not finding K&R helpful on the subject.


Correcting the obvious bug, I don't see any problem. Arrays are
guaranteed to be contiguous, so you'll get no alignment or offset
problems.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"A bicycle cannot stand up by itself because it's two-tyred."
- Sky Text
Nov 13 '05 #2
Joona I Palaste wrote:
Thes <no*@ctually.myaddress.com> scribbled the following:
Hi all,
I have a 2d float array to which I have declared a pointer thus:


float Matrix[4][3] = {/* snipped initialisation */ };
float (*StoredMatrix)[4][3];

So as to create a copy in a program "registry" of my own devising.


I copy the Marix array as follows:


StoredMatrix = malloc(sizeof Matrix);
if(!StoredMatrix)

Surely you mean if (StoredMatrix), or better yet,
if (StoredMatrix != NULL) here? The way you've written here is asking
for trouble.


Oops - yes, that's exactly what I mean. Sorry about that.


{
memcpy((void*)StoredMatrix, (void*)Matrix, sizeof Matrix);
}
else
{ /* take action */ }


My question is whether this is legal, and if so whether it is dangerous?
So far, the copied version dereferences OK using the [] operators - eg
using *StoredMatrix[2][1] etc. I'm not finding K&R helpful on the subject.

Correcting the obvious bug, I don't see any problem. Arrays are
guaranteed to be contiguous, so you'll get no alignment or offset
problems.


Thanks for the reply.

Thes.

Nov 13 '05 #3
On Mon, 10 Nov 2003 16:50:13 +0000, Thes wrote:
I copy the Marix array as follows: [snip] memcpy((void*)StoredMatrix, (void*)Matrix, sizeof Matrix);


The casts to void are unnecessary if you have #included string.h, which
you should do.
Nov 13 '05 #4
Sheldon Simms wrote:
On Mon, 10 Nov 2003 16:50:13 +0000, Thes wrote:

I copy the Marix array as follows:


[snip]
memcpy((void*)StoredMatrix, (void*)Matrix, sizeof Matrix);

The casts to void are unnecessary if you have #included string.h, which
you should do.


Thanks for the tip.

Thes

Nov 13 '05 #5
In <3F**************@ctually.myaddress.com> Thes <no*@ctually.myaddress.com> writes:
I have a 2d float array to which I have declared a pointer thus:

float Matrix[4][3] = {/* snipped initialisation */ };
float (*StoredMatrix)[4][3];

So as to create a copy in a program "registry" of my own devising.

I copy the Marix array as follows:

StoredMatrix = malloc(sizeof Matrix);
if(!StoredMatrix)
{
memcpy((void*)StoredMatrix, (void*)Matrix, sizeof Matrix);
}
This is better written like this:

StoredMatrix = malloc(sizeof *StoredMatrix);
if (StoredMatrix != NULL)
{
memcpy(StoredMatrix, Matrix, sizeof Matrix);
}

Using an explicit test against NULL makes it less likely that you get it
wrong and the casts in the memcpy call are cluttering the code without
buying you anything.
else
{ /* take action */ }

My question is whether this is legal, and if so whether it is dangerous?
So far, the copied version dereferences OK using the [] operators - eg
using *StoredMatrix[2][1] etc. I'm not finding K&R helpful on the subject.


No problems with your code (except for the obvious bug in the if
statement), but it can be improved, so that you can use the
StoredMatrix[2][1] syntax instead of the less natural *StoredMatrix[2][1].

float (*StoredMatrix)[3];
StoredMatrix = malloc(4 * sizeof *StoredMatrix);

Another advantage of this technique is that you can dynamically allocate
"bidimensional" arrays without knowing the number of lines at compile time
only the number of columns must be known.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #6
Dan Pop wrote:
.... snip ...
This is better written like this:

StoredMatrix = malloc(sizeof *StoredMatrix);
if (StoredMatrix != NULL)
{
memcpy(StoredMatrix, Matrix, sizeof Matrix);
}
.... snip ...
No problems with your code (except for the obvious bug in the if


Recalling that Matrix was defined as an array of floats, each of
which may have padding bits and trap values, what guarantees that
those padding bits and trapvalues are independent of the actual
storage location? Thus I suspect that the construct is not
strictly legal, but that the chance of actual problems is
miniscule.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #7
CBFalconer wrote:
Dan Pop wrote:

... snip ...
This is better written like this:

StoredMatrix = malloc(sizeof *StoredMatrix);
if (StoredMatrix != NULL)
{
memcpy(StoredMatrix, Matrix, sizeof Matrix);
}


... snip ...
No problems with your code (except for the obvious bug in the if

Recalling that Matrix was defined as an array of floats, each of
which may have padding bits and trap values, what guarantees that
those padding bits and trapvalues are independent of the actual
storage location? Thus I suspect that the construct is not
strictly legal, but that the chance of actual problems is
miniscule.


Further to that: doing some more testing it seems that when using memcpy
to copy the entire array over to the memory pointed to by the pointer,
there was some problems using [] on the dereferenced pointer. That is,
*StoredMatrix[i][j] didn't always equal Matrix[i][j].

If I copied the matrix using a nested loop in i and j strictly setting
*StoredMatrix[i][j] = Matrix[i][j] then, obviously, all was well.

This behaviour was observed using MSVC++6 but not gcc on Linux - so I
expect I'm doing something undefined somewhere...

Anyway, thanks for the replies. Bad coding habits being curbed!
Thes

Nov 13 '05 #8
In <3F***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:
Dan Pop wrote:
... snip ...

This is better written like this:

StoredMatrix = malloc(sizeof *StoredMatrix);
if (StoredMatrix != NULL)
{
memcpy(StoredMatrix, Matrix, sizeof Matrix);
}

... snip ...

No problems with your code (except for the obvious bug in the if


Recalling that Matrix was defined as an array of floats, each of
which may have padding bits and trap values, what guarantees that
those padding bits and trapvalues are independent of the actual
storage location?


The C standard, of course.
Thus I suspect that the construct is not
strictly legal, but that the chance of actual problems is
miniscule.


Wrong. Note that the padding bits are part of the object representation.

4 Values stored in non-bit-field objects of any other object type
consist of n × CHAR_BIT bits, where n is the size of an object
of that type, in bytes. The value may be copied into an object
of type unsigned char [n] (e.g., by memcpy); the resulting
^^^^^^^^^^^^^^^
set of bytes is called the object representation of the value.
Values stored in bit-fields consist of m bits, where m is the
size specified for the bit-field. The object representation is
the set of m bits the bit-field comprises in the addressable
storage unit holding it. Two values (other than NaNs) with
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the same object representation compare equal, but values that
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
compare equal may have different object representations.

It doesn't hurt to actually consult the standard when elaborating fancy
scenarios...

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #9
In <3F**************@ctually.myaddress.com> Thes <no*@ctually.myaddress.com> writes:
CBFalconer wrote:
Dan Pop wrote:

... snip ...
This is better written like this:

StoredMatrix = malloc(sizeof *StoredMatrix);
if (StoredMatrix != NULL)
{
memcpy(StoredMatrix, Matrix, sizeof Matrix);
}


... snip ...
No problems with your code (except for the obvious bug in the if

Recalling that Matrix was defined as an array of floats, each of
which may have padding bits and trap values, what guarantees that
those padding bits and trapvalues are independent of the actual
storage location? Thus I suspect that the construct is not
strictly legal, but that the chance of actual problems is
miniscule.


Further to that: doing some more testing it seems that when using memcpy
to copy the entire array over to the memory pointed to by the pointer,
there was some problems using [] on the dereferenced pointer. That is,
*StoredMatrix[i][j] didn't always equal Matrix[i][j].


The bug was elsewhere in your code. The value of *any* object, no matter
how large and complex, can be safely copied with memcpy.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #10
Dan Pop wrote:
In <3F**************@ctually.myaddress.com> Thes <no*@ctually.myaddress.com> writes:

CBFalconer wrote:
Dan Pop wrote:

... snip ...
This is better written like this:

StoredMatrix = malloc(sizeof *StoredMatrix);
if (StoredMatrix != NULL)
{
memcpy(StoredMatrix, Matrix, sizeof Matrix);
}
... snip ...
No problems with your code (except for the obvious bug in the if
Recalling that Matrix was defined as an array of floats, each of
which may have padding bits and trap values, what guarantees that
those padding bits and trapvalues are independent of the actual
storage location? Thus I suspect that the construct is not
strictly legal, but that the chance of actual problems is
miniscule.


Further to that: doing some more testing it seems that when using memcpy
to copy the entire array over to the memory pointed to by the pointer,
there was some problems using [] on the dereferenced pointer. That is,
*StoredMatrix[i][j] didn't always equal Matrix[i][j].

The bug was elsewhere in your code. The value of *any* object, no matter
how large and complex, can be safely copied with memcpy.

Dan


Indeed. I've discovered that there is a difference between
*StoredMatrix[i][j] and (*StoredMatrix)[i][j] which suprised me.

What are the rules in these cases?

Thes

Nov 13 '05 #11
Thes <no*@ctually.myaddress.com> scribbled the following:
Dan Pop wrote:
In <3F**************@ctually.myaddress.com> Thes <no*@ctually.myaddress.com> writes:
CBFalconer wrote:
Dan Pop wrote:
>This is better written like this:
>
> StoredMatrix = malloc(sizeof *StoredMatrix);
> if (StoredMatrix != NULL)
> {
> memcpy(StoredMatrix, Matrix, sizeof Matrix);
> }

>No problems with your code (except for the obvious bug in the if

Recalling that Matrix was defined as an array of floats, each of
which may have padding bits and trap values, what guarantees that
those padding bits and trapvalues are independent of the actual
storage location? Thus I suspect that the construct is not
strictly legal, but that the chance of actual problems is
miniscule.

Further to that: doing some more testing it seems that when using memcpy
to copy the entire array over to the memory pointed to by the pointer,
there was some problems using [] on the dereferenced pointer. That is,
*StoredMatrix[i][j] didn't always equal Matrix[i][j].
The bug was elsewhere in your code. The value of *any* object, no matter
how large and complex, can be safely copied with memcpy.

Indeed. I've discovered that there is a difference between
*StoredMatrix[i][j] and (*StoredMatrix)[i][j] which suprised me. What are the rules in these cases?


I'm not altogether sure here, but I think that the first means what
element [i][j] of StoredMatrix points at, and the second means element
[i][j] of what StoredMatrix points at.

--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"Normal is what everyone else is, and you're not."
- Dr. Tolian Soran
Nov 13 '05 #12
In <3F**************@ctually.myaddress.com> Thes <no*@ctually.myaddress.com> writes:
Dan Pop wrote:

The bug was elsewhere in your code. The value of *any* object, no matter
how large and complex, can be safely copied with memcpy.

Indeed. I've discovered that there is a difference between
*StoredMatrix[i][j] and (*StoredMatrix)[i][j] which suprised me.

What are the rules in these cases?


The [] operator having higher precedence, *StoredMatrix[i][j] is the same
as *(StoredMatrix[i][j]), which is NOT what you want in order to access
the element on row i, column j. StoredMatrix[i] is already sending you
beyond the array pointed to by StoredMatrix, if i is not 0.

To preserve your sanity, restrict yourself to pointers to "unidimensional"
arrays, as I've shown in my first post in this thread.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #13
Dan Pop wrote:
CBFalconer <cb********@yahoo.com> writes:

.... snip ...

Recalling that Matrix was defined as an array of floats, each of
which may have padding bits and trap values, what guarantees that
those padding bits and trapvalues are independent of the actual
storage location?


The C standard, of course.
Thus I suspect that the construct is not
strictly legal, but that the chance of actual problems is
miniscule.


Wrong. Note that the padding bits are part of the object representation.

4 Values stored in non-bit-field objects of any other object type
consist of n × CHAR_BIT bits, where n is the size of an object
of that type, in bytes. The value may be copied into an object
of type unsigned char [n] (e.g., by memcpy); the resulting
^^^^^^^^^^^^^^^
set of bytes is called the object representation of the value.
Values stored in bit-fields consist of m bits, where m is the
size specified for the bit-field. The object representation is
the set of m bits the bit-field comprises in the addressable
storage unit holding it. Two values (other than NaNs) with
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the same object representation compare equal, but values that
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
compare equal may have different object representations.

It doesn't hurt to actually consult the standard when elaborating
fancy scenarios...


Why go through an O(N**N) search when we have you to perform those
correlations :-)

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #14
In <3F***************@yahoo.com> CBFalconer <cb********@yahoo.com> writes:
Dan Pop wrote:

It doesn't hurt to actually consult the standard when elaborating
fancy scenarios...


Why go through an O(N**N) search when we have you to perform those
correlations :-)


Maybe because it prevents the brain cells from getting rusty? ;-)

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

27
by: Daniel Lidström | last post by:
Hello! I want to work with individual bytes of integers. I know that ints are 32-bit and will always be. Sometimes I want to work with the entire 32-bits, and other times I want to modify just...
9
by: sakitah | last post by:
Here is what I have: struct SubList { int BookId; int WFreq; }; struct Listing {
5
by: junky_fellow | last post by:
Consider a 3-dimensional array: char a = { "abcd", "efgh", "ijkl" , "mnop", "qrst", "uvwx" } ; when i print the addresses for a,a and a they are same. but when i access element a+1, a+1 and...
8
by: Dawn Minnis | last post by:
Hey guys If I have a program (see codeSnippet1) that I compile to be called test.o Then run it as test.o n n 2 3 4 I want the code to be able to strip out the two characters at the start...
6
by: archilleswaterland | last post by:
structures typedef struct{ char name; int age; float balance; }account; account xyx; accout *ptr;
0
by: harsha1305 | last post by:
Hi all, I need to create a pointer to array of structure. Definition of structure: typedef struct { char b_name; unsigned long int sig; unsigned long int count; volatile unsigned char...
38
by: djhulme | last post by:
Hi, I'm using GCC. Please could you tell me, what is the maximum number of array elements that I can create in C, i.e. char* anArray = (char*) calloc( ??MAX?? , sizeof(char) ) ; I've...
2
by: ...vagrahb | last post by:
I am having accessing individual rows from a multidimensional array pass to a function as reference CODE: function Declaration int Part_Buffer(char (*buffer),int Low, int High)
16
by: s0suk3 | last post by:
This code #include <stdio.h> int main(void) { int hello = {'h', 'e', 'l', 'l', 'o'}; char *p = (void *) hello; for (size_t i = 0; i < sizeof(hello); ++i) {
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.