我能够"打包"字符串长的数组。现在,如果我memcpy包含long数组的字符串,内容就会丢失。在这里你有我的代码:
#include <stdio.h>
#include <string.h>
int main()
{
unsigned char arr[40];
unsigned char arr2[40];
unsigned int i = 0 ;
long f=0;
for ( i = 0 ; i < 5 ; i++ ) {
f = i + 1 ;
*((long *)arr + i*sizeof(long)) = f ;
}
memcpy(arr2, arr, 40);
for ( i = 0 ; i < 5 ; i++ ) {
f = *((long *)arr2 + i*sizeof(long)) ;
printf("f =%ld from arr2 sizeof %zu\n", f, (size_t)(i*sizeof(long)));
}
for ( i = 0 ; i < 5 ; i++ ) {
f = *((long *)arr + i*sizeof(long)) ;
printf("f =%ld from arr sizeof %zu\n", f, (size_t)(i*sizeof(long)));
}
}
这是输出:
f =1 from arr2 sizeof 0
f =0 from arr2 sizeof 8
f =1 from arr2 sizeof 16
f =140734674541394 from arr2 sizeof 24
f =140734674541702 from arr2 sizeof 32
f =1 from arr sizeof 0
f =2 from arr sizeof 8
f =3 from arr sizeof 16
f =4 from arr sizeof 24
f =5 from arr sizeof 32
正如你所看到的,我能够阅读我在&#34; arr&#34;中存储的长值。但不是来自&#34; arr2&#34;。任何线索?
答案 0 :(得分:2)
*((long *)arr + i) = f ;
将导致未定义的行为。 (long *)arr2 + i*sizeof(long)
已在(long *)arr2 + i
中编入索引。
所以你写了sizeof(long)
的结尾,但只复制它的前40个字节。除此之外,对于未定义的行为没有任何理由。如果你幸运的话,它会崩溃,因此立即表明你做了一些非常错误的事情。
答案 1 :(得分:1)
问题是你将(衰变的)指针arr
和arr2
强制转换为long*
,然后你不再有一个数组ob字节而是一个{{1所以你的指针算术将不再正确(它假定指针是long
的指针)。删除乘法,就像这样。
char
答案 2 :(得分:1)
将1
添加到指针p
和sizeof(*p) == 8
时,它等同于将8
添加到char
指针。
换句话说,一旦你投射指针,就不再需要扩展索引了。
#include <stdio.h>
#include <string.h>
int main()
{
unsigned char arr[40];
unsigned char arr2[40];
unsigned int i = 0 ;
long f=0;
for ( i = 0 ; i < 5 ; i++ ) {
f = i + 1 ;
*((long *)arr + i) = f ;
}
memcpy(arr2, arr, 40);
for ( i = 0 ; i < 5 ; i++ ) {
f = *((long *)arr2 + i) ;
printf("f =%ld from arr2 sizeof %zu\n", f, (size_t)(i*sizeof(long)));
}
for ( i = 0 ; i < 5 ; i++ ) {
f = *((long *)arr + i) ;
printf("f =%ld from arr sizeof %zu\n", f, (size_t)(i*sizeof(long)));
}
}
从技术上讲,您的程序仍然未定义,因为它违反了严格别名。您可以通过使用long数组并通过char指针访问它,使用动态内存而不是堆栈分配的数组,或者通过在循环的每次迭代中将char字节memcp into临时long来解决这个问题(gcc可以采用提示和最后一个解决方案根本不会效率低下,尽管看似昂贵的函数调用。)
答案 3 :(得分:1)
您的问题出现在几个表达式中
*((long *)arr + i*sizeof(long))
您需要决定是否在char
指针或long
指针上进行指针算法。
如果您想在char
指针上执行此操作,请从arr
开始,添加i * sizeof(long),然后转换为long
指针:
arr
arr + i*sizeof(long)
(long *)(arr + i*sizeof(long))
另一方面,您也可以先将arr
转换为long
指针。但是,您不必乘以sizeof(long)
,因为long
指针上的算术以sizeof(long)
为单位,而不是字节:
arr
(long *)arr
((long *)arr + i)