库错误还是我的错? [英] Library bug or my fault?
问题描述
请查看邮件末尾列出的示例代码。这是使用ARM / Linux交叉编译器编译并在ARM9目标上运行的
。我认为这个问题适用于这个组,因为来自不同供应商的两个交叉编译器
导致相同的错误。所以我猜这不是供应商<br />
具体。如果我的猜测是对的,那就意味着代码本身可能会出现问题,但我无法弄清楚它在哪里。
问题是,第38行复制3个字节,从p2开始,到
p1,但紧接着的memcmp(第42行)显示memcpy是
做得不好。我确信memcpy没有完成这项工作,因为如果我提供我自己的memcpy实现,如下所示,错误将会消失。
消失。
void memcpy(void * dest,void * src,size_t n)
{
uint8_t * d =(uint8_t *)dest;
uint8_t * s =(uint8_t *)src;
for(size_t i = 0; i< n; ++ i)
* d ++ = * s ++;
}
您能否查看代码以及运行结果和
告诉我有什么不对吗?谢谢。
-------------------------------------最小样本
------------------------------------------ --------
1 #include< stdio.h>
2 #include< string>
3# include< stdint.h>
4 #include< assert.h>
5
6 struct Foo {
7 uint8_t x;
8 uint8_t y;
9 uint8_t z;
10 uint8_t m [3];
11};
12
13 struct Bar
14 {
15 uint8_t m [3 ];
16};
17
18 void pr(const char * title,const void * block,size_t n)
19 {
20 printf("%s\ n",title);
21
22 uint8_t * p =(uint8_t *)block;
23 for(size_t i = 0; i< n; ++ i)
24 printf(" 0x%02x" ;,* p ++);
25
26 printf(" \ n");
27}
28
29 v oid cp(const Foo * foo)
30 {
31酒吧酒吧;
32
33 Bar * p1 =& bar;
34 Bar * p2 =(Bar *)(foo-> m);
35 pr(" before:p1:" ,p1,3;;
36 pr(之前:p2:,p2,3 ;;
37
38 memcpy (p1,p2,3);
39 pr(" after:p1:",p1,3);
40 pr(" after:p2: ",p2,3 ;;
41
42 if(memcmp(p1,p2,3)!= 0)
43 printf (QUOT;! cp是错的\ n;
44}
45
46 int main()
47 {
48 Foo foo;
49 foo.x = 1;
50 foo.y = 2;
51 foo.z = 3;
52 foo.m [0] = 0x40;
53 foo.m [1] = 0x19;
54 foo.m [2] = 0x21;
55
56 cp(& foo);
57 cp2(& foo);
58返回0;
59}
----------------- ------------------------------------------------- <下面是ARM920T板上的运行输出:
之前:p1:
0xfc 0x01 0x12
之前:p2:
0x40 0x19 0x21
之后:p1:
0x40 0x01 0x02
之后:p2:
0x40 0x19 0x21
!!! cp错了
Steven Woody写道:
...
问题是,第38行复制3个字节,从
p2开始,再到p1,但紧随其后的memcmp(第42行)
显示memcpy做得不好。
这是前面的线路表示问题。
------ -------------------------------最小样本
-------- ------------------------------------------
1 #include< stdio.h>
2 #include< string>
3 #include< stdint.h>
4 #include< assert.h>
5
6 struct Foo {
7 uint8_t x;
8 uint8_t y;
9 uint8_t z;
10 uint8_t m [3];
11};
12
13 struct bar
14 {
15 uint8_t m [3];
16};
这些是完全不同的结构。
29 void cp(const Foo * foo)
30 {
31吧台酒吧;
32
33 Bar * p1 =& bar;
34 Bar * p2 =(Bar *)(foo-> m);
事实上你有一个强制转换警告(或者更可能是因为
错误)而导致不兼容类型的问题。 Bar不是一个数组,
它是一个包含数组的结构。
标准允许转换(如果foo-> m对齐
正确),但它没有更多说明。只有你转换它
返回它必须比较相等。
35 pr(" before:p1:",p1,3 );
36 pr(之前:p2:,p2,3;)
38 memcpy(p1,p2 ,3);
如果你真的想这样做,那么以下内容应该有效...
memcpy(bar-> m,foo-> m,sizeof foo-> m);
如果失败了,你可以担心。
你有其他的选择,比如把一个Bar结构放在foo里面。
你可以使用Bar指针和简单的赋值。
但从根本上说,你应该复制喜欢。
< snip>
-
Peter
在文章< be ********************************** @ s50g2000hsb。 googlegroups.com>,
Steven Woody< na ******** @ gmail.comwrote:
> 1 #include< stdio.h>
2 #include< string>
应该是
#include< string.h>
你需要< string.h为memcpy原型。
问候,
Ike
Steven Woody写道:
请查看邮件末尾列出的示例代码。
它似乎是用一些非C语言编写的。你的意思是
而不是发布到C ++?看看这个版本(注意更改,更多
可能是可取的,但我只解决可能是你的问题)工作
给你。显然可能存在问题(例如,
你确定访问''bar''的未初始化内容是安全的吗?)。
# include< stdio.h>
#include< string.h / * mha:was''string''* /
#include< stdint.h>
struct Foo
{
uint8_t x;
uint8_t y;
uint8_t z;
uint8_t m [3];
};
struct Bar
{
uint8_t m [3];
};
void pr(const char * title,const void * block,size_t n)
{
printf("%s \ n",title);
uint8_t * p =(uint8_t *)block;
for(size_t i = 0; i< n; ++ i)
printf(" 0x%02x", * p ++);
printf(" \ n");
}
void cp( const struct Foo / * mha:添加了所需的''struct''* / * foo)
{
struc t酒吧; / * mha:在这里添加了''struct''&
以下* /
struct Bar * p1 =& bar;
struct Bar * p2 =(struct Bar *)(foo-> m);
pr(" before:p1:",p1,3);
pr(之前:p2:,p2,3 ;;
memcpy(p1,p2,3);
pr(&after; after :p1:",p1,3 ;;
pr(" after:p2:",p2,3);
if(memcmp (p1,p2,3)!= 0)
printf(!!! cp是错的\ n);
}
int main()
{
struct Foo foo; / * mha:添加需要''struct''* /
foo.x = 1;
foo.y = 2;
foo .z = 3;
foo.m [0] = 0x40;
foo.m [1] = 0x19;
foo.m [2] = 0x21;
cp(& foo);
返回0;
}
之前:p1:
0x20 0x20 0x20
之前:p2:
0x40 0x19 0x21
之后:p1:
0x40 0x19 0x21
之后:p2:
0x40 0x19 0x21
当然输出与你的不同。
以下是ARM920T板上的运行输出:
之前:p1:
0xfc 0x01 0x12
之前:p2:
0x40 0x19 0x21
之后:p1:
0x40 0x01 0x02
之后:p2:
0x40 0x19 0x21
Hi,
Please check the sample code listed in the end of the message. It was
compiled using ARM/Linux cross-compiler and run on an ARM9 target. I
think the problem applies to this group because two cross-compiler
from different vendor result same error. So I guess it is not vendor
specific. If my guess is right, then it means the code itself may get
problem, but I can not figure out where it is.
The problem is, the line 38 which copy 3 bytes, starting from p2, to
p1, but the immediately followed memcmp (line 42) shows the memcpy was
not well done. I am sure the memcpy did not do the job, since if I
provide my own memcpy implemention as below, the error will go
disappear.
void memcpy(void *dest, void *src, size_t n)
{
uint8_t *d = (uint8_t*)dest;
uint8_t *s = (uint8_t*)src;
for (size_t i = 0; i < n; ++i)
*d++ = *s++;
}
Could you please check the code as well as the running result and
tell me what wrong with it? Thanks.
------------------------------------- the minimum sample
--------------------------------------------------
1 #include <stdio.h>
2 #include <string>
3 #include <stdint.h>
4 #include <assert.h>
5
6 struct Foo {
7 uint8_t x;
8 uint8_t y;
9 uint8_t z;
10 uint8_t m[3];
11 };
12
13 struct Bar
14 {
15 uint8_t m[3];
16 };
17
18 void pr(const char *title, const void *block, size_t n)
19 {
20 printf("%s\n", title);
21
22 uint8_t *p = (uint8_t*)block;
23 for (size_t i = 0; i < n; ++i)
24 printf("0x%02x ", *p++);
25
26 printf("\n");
27 }
28
29 void cp(const Foo *foo)
30 {
31 Bar bar;
32
33 Bar *p1 = &bar;
34 Bar *p2 = (Bar*)(foo->m);
35 pr("before: p1:", p1, 3);
36 pr("before: p2:", p2, 3);
37
38 memcpy(p1, p2, 3);
39 pr("after: p1:", p1, 3);
40 pr("after: p2:", p2, 3);
41
42 if (memcmp(p1, p2, 3) != 0)
43 printf("!!! cp is wrong\n");
44 }
45
46 int main()
47 {
48 Foo foo;
49 foo.x = 1;
50 foo.y = 2;
51 foo.z = 3;
52 foo.m[0] = 0x40;
53 foo.m[1] = 0x19;
54 foo.m[2] = 0x21;
55
56 cp(&foo);
57 cp2(&foo);
58 return 0;
59 }
------------------------------------------------------------------
Below is the running output on an ARM920T board:
before: p1:
0xfc 0x01 0x12
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x01 0x02
after: p2:
0x40 0x19 0x21
!!! cp is wrong
Steven Woody wrote:...
The problem is, the line 38 which copy 3 bytes, starting from
p2, to p1, but the immediately followed memcmp (line 42)
shows the memcpy was not well done.It''s the lines before that signal a problem.
------------------------------------- the minimum sample
--------------------------------------------------
1 #include <stdio.h>
2 #include <string>
3 #include <stdint.h>
4 #include <assert.h>
5
6 struct Foo {
7 uint8_t x;
8 uint8_t y;
9 uint8_t z;
10 uint8_t m[3];
11 };
12
13 struct Bar
14 {
15 uint8_t m[3];
16 };These are completely different structs.
29 void cp(const Foo *foo)
30 {
31 Bar bar;
32
33 Bar *p1 = &bar;
34 Bar *p2 = (Bar*)(foo->m);The fact you have a cast to silence a warning (or more likely
error) on incompatible types is the problem. Bar is not an array,
it is a struct containing an array.
The standard allows the conversion (if foo->m is aligned
properly), but it says nothing more. Only if you convert it
back must it compare equal.
35 pr("before: p1:", p1, 3);
36 pr("before: p2:", p2, 3);
37
38 memcpy(p1, p2, 3);If you really wanted to do this, then the following should work...
memcpy(bar->m, foo->m, sizeof foo->m);
If that fails, you have cuase for concern.
You have other options, like putting a Bar struct inside foo.
The you can use Bar pointers and simple assignment.
But fundamentally, you should be copying like to like.
<snip>
--
Peter
In article <be**********************************@s50g2000hsb. googlegroups.com>,
Steven Woody <na********@gmail.comwrote:>1 #include <stdio.h>
2 #include <string>That should be
#include <string.h>
You need <string.hfor the memcpy prototype.
Regards,
Ike
Steven Woody wrote:Hi,
Please check the sample code listed in the end of the message.It seems to be written in some non-C but C-like language. Did you mean
to post to C++ instead? See if this version (notice the changes, more
may be advisable, but I address only what might be your problem) works
for you. There are clearly possible problems remaining (for example,
are you sure that accessing the uninitialized contents of ''bar'' is safe?).
#include <stdio.h>
#include <string.h /* mha: was ''string'' */
#include <stdint.h>
struct Foo
{
uint8_t x;
uint8_t y;
uint8_t z;
uint8_t m[3];
};
struct Bar
{
uint8_t m[3];
};
void pr(const char *title, const void *block, size_t n)
{
printf("%s\n", title);
uint8_t *p = (uint8_t *) block;
for (size_t i = 0; i < n; ++i)
printf("0x%02x ", *p++);
printf("\n");
}
void cp(const struct Foo /* mha: added needed ''struct'' */ *foo)
{
struct Bar bar; /* mha: added needed ''struct'' here &
below */
struct Bar *p1 = &bar;
struct Bar *p2 = (struct Bar *) (foo->m);
pr("before: p1:", p1, 3);
pr("before: p2:", p2, 3);
memcpy(p1, p2, 3);
pr("after: p1:", p1, 3);
pr("after: p2:", p2, 3);
if (memcmp(p1, p2, 3) != 0)
printf("!!! cp is wrong\n");
}
int main()
{
struct Foo foo; /* mha: added need ''struct'' */
foo.x = 1;
foo.y = 2;
foo.z = 3;
foo.m[0] = 0x40;
foo.m[1] = 0x19;
foo.m[2] = 0x21;
cp(&foo);
return 0;
}
before: p1:
0x20 0x20 0x20
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x19 0x21
after: p2:
0x40 0x19 0x21
Certainly the output is different from yours.
Below is the running output on an ARM920T board:
before: p1:
0xfc 0x01 0x12
before: p2:
0x40 0x19 0x21
after: p1:
0x40 0x01 0x02
after: p2:
0x40 0x19 0x21
这篇关于库错误还是我的错?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!