6

How to copy char array to char array using int in C

 2 years ago
source link: https://www.codesd.com/item/how-to-copy-char-array-to-char-array-using-int-in-c.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How to copy char array to char array using int in C

advertisements

As an academic task I need to copy char array to char array using integer variable to copy 4 chars at once in every iteration. I'm aware that there are specialised functions to do that, it's just the matter of exercise. I tried as below:

char source[SIZE];
//populate chars in source
char dest[SIZE];
for (int i = 0; i < (SIZE + 3) / 4; i++)
{
    int number = *(int*)(source + 4 * i);
    *(dest + 4 * i) = (int)number;
}

The result is that only every fourth element is properly copied so I suppose I mixed something up with pointers. How should I correct it?


The writing part is wrong, you write to

*(dest + 4 * i)

and as dest is a pointer to char, the type of this expression still is char. The cast for number is not needed, it is already an int. So the "correct" line would be:

*(int *)(dest + 4 * i) = number;

I write "correct" in quotes because according to standard C, aliasing pointers with a different type is not allowed. As an exception, a char pointer may alias any other pointer, but here you do it the other way around, this is by no means guaranteed to work as expected.

Also note that what you do is unnecessarily complicated, you could just alias an int * to the start of your array and increment that pointer by one to get the next int, or use simple indexers. It could look as simple as:

char source[SIZE];
//populate chars in source
char dest[SIZE];

int *srcptr = (int *)source;
int *dstptr = (int *)dst;
for (int i = 0; i < SIZE / sizeof(int); ++i)
{
    dstptr[i] = srcptr[i];
}


Be aware this is not at all portable: It depends on some properties like the machine not requiring alignment for int, not using any padding bits, etc.

And finally, a little example of how this could go wrong even when these assumptions are met, as e.g. on x86:

char source[SIZE];
char dest[SIZE];

source[0] = 'a';
dest[0] = 'b';

int *srcptr = (int *)source;
int *dstptr = (int *)dst;

for (int i = 0; i < SIZE / sizeof(int); ++i)
{
    dstptr[i] = srcptr[i];
}

printf("%c\n", dest[0]); // <- might output 'b'

This is a stupid example for simplicity, but an aggressively optimizing compiler might indeed optimize away the final read from dest[0] because it "knows" from the lines above it holds the value 'b'. Because pointers to a different type are not allowed to alias the array, the logic is, nothing in this program could possibly alias. Not so obvious in this stupid example, but with more complex programs, there might be really no way for the compiler to determine whether pointers alias each other, so the strict aliasing rule makes the decision easier on which optimization is allowed.

Tags arrays

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK