memcpy to arrays

This topic is 4328 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

If if have some arrays:
short Array1[101][101][2], x[202];
and I memcpy to Array1:
for(loopf1=0;loopf1<101;loopf1++){
memcpy(&Array1[loopf1][0][0],x,(202*sizeof(short)));
}
Why would another variable get overwritten? Two other variables that I'm using get overwritten when loopf1==37.

Share on other sites
You should avoid using memcpy() generally, and rather use dynamic containers like std::list or std::vector, as these are much less error-prone than memcpy'ing things in arrays around yourself.

Share on other sites
I've never used that notation before. Can you do that in C, or just C++? Or am I way off?

Share on other sites
Quote:
 Original post by NoobwakerI've never used that notation before. Can you do that in C, or just C++? Or am I way off?

What lucem recommended is C++ only (It's a part of the SC++L). On this forum most people automatically assume you use C++.

EDIT: Fixed names

Share on other sites
Quote:
Original post by CTar
Quote:
 Original post by NoobwakerI've never used that notation before. Can you do that in C, or just C++? Or am I way off?

What Noobwaker recommended is ...

Hmm... was he talking to him/herself [grin].

Share on other sites
Basically, these are part of the C++ Standard template library.
As most compilers today are C++ compilers, you can use them from C, too, in most cases.
These containers, algortihms and iterators in the STL (and in other libs, too, like Boost:: for example) are really handy, as they base on templates and so a generic containers you can use with every data type.
They handle memory management for you and keep you away from producing segfaults ;), so all you have to do is use them, which simplifies development a lot a times.

Share on other sites
A quick test run with your code doesn't reveal any problems with the memory on either side of Array1 and x, and it looks OK to me [if not a little silly]. What exactly is getting overwritten?

CM

Share on other sites
it could be possible. if i remember correctly memmove is one function that handles overlapping boundaries. give memmove a try. though one question i have is (since it's been a while since i've used C...) are multidimensional arrays defined to be contiguous (is &Array[i][j] + 2 == &Array[i][j + 1]? i mean if done with new you'd have problems cuz your array size is technically 2, not 202.

short*** Array1 = new (short**)[101];for(i = 0; i < 101; i++) {    Array1[i] = new (short*)[101];    for(j = 0; j < 101; j++) Array[i][j] = new short[2];   }

[Edited by - yadango on March 12, 2006 11:17:35 AM]

Share on other sites
Quote:
 Original post by yadangoit could be possible. if i remember correctly memmove is one function that handles overlapping boundaries. give memmove a try. though one question i have is (since it's been a while since i've used C...) are multidimensional arrays defined to be contiguous (is &Array[i][j] + 2 == &Array[i][j + 1]?

Yes, they are defined to be contiguous, although your example is flawed since pointer arithmetic automatically acounts for type sizes. This assumes the array is statically defined...you can't use malloc for obvious reasons. I'm also not sure whether or not row-major or column-major forms are required. I'm not even sure which is used, since I always have to look up what those words mean. That, by the way, was my first guess. That the wrong ordering was being assumed, so bounds weren't adding up the way he thought they would.

CM

Share on other sites
The two variables, which are Map.SizeX and Map.SizeY, get overwritten when the loopf1 is 37. If I make x only 201, and memcpy only (201*sizeof(short)), then Array1[loopf1][100][0] gets written to, but Array1[loopf1][100][1] doesn't. So I don't think it's any overflow. Array1 and the Map variables are global, and x is local.

Is there something else I can do that would be just as fast or faster?

(I'm using C incase you don't know)

Share on other sites
Quote:
 Original post by NoobwakerIf if have some arrays:short Array1[101][101][2], x[202];and I memcpy to Array1:for(loopf1=0;loopf1<101;loopf1++){ memcpy(&Array1[loopf1][0][0],x,(202*sizeof(short)));}Why would another variable get overwritten?Two other variables that I'm using get overwritten when loopf1==37.

Your code looks correct to me (like it did to others). The suggestion is now that you copy and paste (don't type, you may make typos) an actual code block to exhibits the problem. Preferably, the code block should be a complete program that we can compile.

Here's an example of what such a block could look like (even though it doesn't appear to exhibit your problem):
#include <stdio.h>#include <string.h>int main(void) {    short Array1[101][101][2], x[202];    size_t loopf1;    for (loopf1 = 0; loopf1 < 202; loopf1++) {        x[loopf1] = loopf1;    }    for (loopf1 = 0; loopf1 < 101; loopf1++) {	  memcpy(Array1[loopf1], x, 202 * sizeof(short));    }    for (loopf1 = 0; loopf1 < 101; loopf1++) {        size_t loopf2;        for (loopf2 = 0; loopf2 < 101; loopf2++) {            printf("%d %d ", (int)Array1[loopf1][loopf2][0], (int)Array1[loopf1][loopf2][1]);        }        printf("\n");    }    return 0;}

Here's one that uses "sizeof var" instead of "sizeof(type)" and magic numbers to help avoid errors (in particular for the memcpy):
#include <stdio.h>#include <string.h>#define MIN(a_, b_) ((a_) < (b_) ? (a_) : (b_))#define N(a_)       (sizeof a_ / sizeof *a_)int main(void) {    short Array1[101][101][2], x[202];    size_t loopf1;    for (loopf1 = 0; loopf1 < N(x); loopf1++) {        x[loopf1] = loopf1;    }    for (loopf1 = 0; loopf1 < N(Array1); loopf1++) {	  memcpy(Array1[loopf1], x, MIN(sizeof Array1[0], sizeof x));    }    for (loopf1 = 0; loopf1 < N(Array1); loopf1++) {        size_t loopf2;        for (loopf2 = 0; loopf2 < N(*Array1); loopf2++) {            printf("%d %d ", (int)Array1[loopf1][loopf2][0], (int)Array1[loopf1][loopf2][1]);        }        printf("\n");    }    return 0;}

Share on other sites
Wow, I just found out something really messed up.
	path[37][84][0]=9;	path[37][84][1]=14;

sets Map.SizeX to 9, and Map.SizeY to 14.

What's going on?

Share on other sites
Quote:
 Original post by NoobwakerWow, I just found out something really messed up. path[37][84][0]=9; path[37][84][1]=14;sets Map.SizeX to 9, and Map.SizeY to 14.What's going on?

You have a bug. To be more specific, you either have an overflow or an aliasing problem. Without actual code (*hint* *hint*), it's hard to say exactly what's wrong.

Share on other sites
So... what is aliasing?

Share on other sites
Quote:
 Original post by NoobwakerWow, I just found out something really messed up. path[37][84][0]=9; path[37][84][1]=14;sets Map.SizeX to 9, and Map.SizeY to 14.What's going on?

To understand what's going on, it's better that you back up a bit and do this with a 2D array. static arrays are contigous. Meaning, if you went out of bounds in a 2D array with the first row, you would land in the second row (assuming you're still within range). This works because of the contigousness, but, it's not recommended that you program this way =)

For example:

char twod[2][10]; // ROW and COLUMEtwod[0][10] = 'k';

would set the character value 'k' at indexe's 1 (row) and 0 (colume).

- xeddiex

Share on other sites
path[37][84][0] should still be in range though since the declaration is
short path[101][101][2];
But my problem is that somehow Map.SizeX is connected with path[37][84][0]. How does something like that happen, and how can I fix it?

Share on other sites
Aliasing is when you have two names for the same data. The most trivial example is:
int a = 1;int *b = &a;int *c = &a;

A less trivial example is:
int a[2] = {1, 2};int *b = a;int *c = a + 1;

Because here b[1] and *c are the same. Overflow is very similar:
int a[1] = {1};int b = 2;

Here, a[1] might give you b.

Quote:
 Original post by NoobwakerHow does something like that happen, and how can I fix it?

I don't have enough information to answer that question. Take off the tinfoil hat and give us some code to work with.

Share on other sites
Quote:
 Original post by Noobwakerpath[37][84][0] should still be in range though since the declaration is short path[101][101][2];But my problem is that somehow Map.SizeX is connected with path[37][84][0]. How does something like that happen, and how can I fix it?

We can't tell you what's going on, because, as you noticed, it shouldn't be happening in the first place. This means that something elsewhere must be the problem. Until we see that something elsewhere, you aren't going to get any help.

CM

loopf1=Map.SizeX;path[37][84][0]++;