库错误还是我的错? [英] Library bug or my fault?

查看:45
本文介绍了库错误还是我的错?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




请查看邮件末尾列出的示例代码。这是使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆