memcpy今天用错两次

caddor 2012-01-04 05:51:09
第一次:

拷贝 两个unsigned int 数组


居然引起 负数的出现,

无奈之下,用for循环进行拷贝!!!!




第二次:


拷贝字符串,又出错


具体代码不在手头, 以下是伪代码:

CString str="123"

char s[20];

memcpy(s,(char*)(LPCTSTR)str,20);


多次运行以代码,居然出错。。。。。。。。。。。。。




开始怀疑memcpy函数了。。。。。




第三个参数,是长度,我铁定是正确的。。。。。。。

...全文
443 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2012-01-05
  • 打赏
  • 举报
回复
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
nice_cxf 2012-01-05
  • 打赏
  • 举报
回复
unsigned int 能出负数?确定?
eternalxlm 2012-01-05
  • 打赏
  • 举报
回复
unsigned int弄出负数,你打印的时候没按无符号吧
daviddb7 2012-01-05
  • 打赏
  • 举报
回复
第一个问题贴代码啊,unsigned int能搞出负数来,我也想看看LZ是怎么做的。
caddor 2012-01-05
  • 打赏
  • 举报
回复
第一个问题,出现负数, 我无法贴代码,

是别人调用我的代码。。。。。


谢谢大家了。。。。

memcpy是可以拷贝两个大小相同的unsigned int 数组的

chouxiaoya8100 2012-01-04
  • 打赏
  • 举报
回复
多谢了啊


能解释 第一个问题吗




[Quote=引用 16 楼 dourgulf 的回复:]
应该是使用CString的方法取得字符串的长度吧。
memcpy(s,(char*)(LPCTSTR)str, str.GetLength()+1);

直接取20明显是访问越界了,和memcpy无关。
[/Quote]
子达如何 2012-01-04
  • 打赏
  • 举报
回复
应该是使用CString的方法取得字符串的长度吧。
memcpy(s,(char*)(LPCTSTR)str, str.GetLength()+1);

直接取20明显是访问越界了,和memcpy无关。
chouxiaoya8100 2012-01-04
  • 打赏
  • 举报
回复
这么多帖子,感觉你的说到点子上了


是不是这样理解:

memcpy比strcpy安全,是因为可以防止'\0'

但是如果它一旦指定错误字节数,就会越界。。。。

当然吗,如果CString 超过20个字节, 什么问题都没有。。。


它少于20个的时候,很容易出问题,

第一次运行的时候,程序没有问题


多次运行后,立即memcpy报错。。。

strcpy是 会引入'\0'带来的问题



、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

第一个问题,依然没有得到较好的解释。,。

两个大小一样的unsigned short 数组,进行拷贝,多次运行后,出错




CString

[Quote=引用 13 楼 qq120848369 的回复:]
。。。这个用strcpy。。。 不能memcpy。。。 你怎么知道CString里有20个字节的字符串的。。。
[/Quote]
frankjiangjieqi 2012-01-04
  • 打赏
  • 举报
回复

/* MEMCPY.C: Illustrate overlapping copy: memmove
* handles it correctly; memcpy does not.
*/

#include <memory.h>
#include <string.h>
#include <stdio.h>

char string1[60] = "The quick brown dog jumps over the lazy fox";
char string2[60] = "The quick brown fox jumps over the lazy dog";
/* 1 2 3 4 5
* 12345678901234567890123456789012345678901234567890
*/

void main( void )
{
printf( "Function:\tmemcpy without overlap\n" );
printf( "Source:\t\t%s\n", string1 + 40 );
printf( "Destination:\t%s\n", string1 + 16 );
memcpy( string1 + 16, string1 + 40, 3 );
printf( "Result:\t\t%s\n", string1 );
printf( "Length:\t\t%d characters\n\n", strlen( string1 ) );

/* Restore string1 to original contents */
memcpy( string1 + 16, string2 + 40, 3 );

printf( "Function:\tmemmove with overlap\n" );
printf( "Source:\t\t%s\n", string2 + 4 );
printf( "Destination:\t%s\n", string2 + 10 );
memmove( string2 + 10, string2 + 4, 40 );
printf( "Result:\t\t%s\n", string2 );
printf( "Length:\t\t%d characters\n\n", strlen( string2 ) );

printf( "Function:\tmemcpy with overlap\n" );
printf( "Source:\t\t%s\n", string1 + 4 );
printf( "Destination:\t%s\n", string1 + 10 );
memcpy( string1 + 10, string1 + 4, 40 );
printf( "Result:\t\t%s\n", string1 );
printf( "Length:\t\t%d characters\n\n", strlen( string1 ) );
}


qq120848369 2012-01-04
  • 打赏
  • 举报
回复
。。。这个用strcpy。。。 不能memcpy。。。 你怎么知道CString里有20个字节的字符串的。。。
caddor 2012-01-04
  • 打赏
  • 举报
回复
结果真的是负数。。。

界面层不知道为什么显示了负数。。。。


我无奈之下,将memcpy去掉。。。

改成用for 循环拷贝两个数组。。。。


就没有出现了负数。。。。。




对于第二个问题;

123'\0' 再加上它后面的字节。。。。

都会被拷贝到s中。。。。。

由于s是字符数组, '\0' 被拷贝到了s中,

起到了了截断的作用啊。。

这样s就安全了。。。。。。






[Quote=引用 5 楼 mingliang1212 的回复:]

1.unsigned int 绝对不可能是负数.因为他不能表示负数.

2.
CString str="123"

char s[20];

memcpy(s,(char*)(LPCTSTR)str,20);这个必须错.

CString是一个类.不是一串字符...要想知道为什么就学C++吧...
[/Quote]
caddor 2012-01-04
  • 打赏
  • 举报
回复
你好


多字节下是 TCHAR 就变成了char了



[Quote=引用 7 楼 mingliang1212 的回复:]

memcpy(s,(char*)(LPCTSTR)str,20);这个必须错.

CString是一个类.不是一串字符...要想知道为什么就学C++吧...
============

修正一下...不记得那丫重载了LPCTSTR了..但是这个是TCHAR类型的字符串,而不是char
[/Quote]
caddor 2012-01-04
  • 打赏
  • 举报
回复
运算符重载

[Quote=引用 8 楼 nice_cxf 的回复:]

发C++去吧,c里面没有类
(LPCTSTR)str CString这样强转可以么?
[/Quote]
IVERS0N 2012-01-04
  • 打赏
  • 举报
回复
围观了
nice_cxf 2012-01-04
  • 打赏
  • 举报
回复
发C++去吧,c里面没有类
(LPCTSTR)str CString这样强转可以么?
iamnobody 2012-01-04
  • 打赏
  • 举报
回复
memcpy(s,(char*)(LPCTSTR)str,20);这个必须错.

CString是一个类.不是一串字符...要想知道为什么就学C++吧...
============

修正一下...不记得那丫重载了LPCTSTR了..但是这个是TCHAR类型的字符串,而不是char
caddor 2012-01-04
  • 打赏
  • 举报
回复
我知道是4,

可是你想, 123'\0' 再加上它后面的字节。。。。

都会被拷贝到s中。。。。。

由于s是字符数组, '\0'

取到了截断的作用啊。。。。

为何出错

[Quote=引用 2 楼 qscool1987 的回复:]
memcpy(s,(char*)(LPCTSTR)str,20);
你第三个参数应该是4
MSDN查下用法,看你都不理解啊
[/Quote]
iamnobody 2012-01-04
  • 打赏
  • 举报
回复
1.unsigned int 绝对不可能是负数.因为他不能表示负数.

2.
CString str="123"

char s[20];

memcpy(s,(char*)(LPCTSTR)str,20);这个必须错.

CString是一个类.不是一串字符...要想知道为什么就学C++吧...

wesleyluo 2012-01-04
  • 打赏
  • 举报
回复
什么情况,用了这么久才发现问题???不可能吧。
面包大师 2012-01-04
  • 打赏
  • 举报
回复
第三个参数错了。。。应该是第二个参数的长度,越界了。。。
加载更多回复(2)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧