免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1879 | 回复: 8
打印 上一主题 下一主题

★同一种内存分配方式,两种不同结果 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-12-28 11:02 |只看该作者 |倒序浏览
程序:
第一种情况:

  1. #include <iostream>
  2. #include <cstdlib>
  3. using namespace std;

  4. typedef struct
  5. {
  6.         char *data;
  7. }Buf;

  8. int main()
  9. {
  10.         Buf myBuf;
  11.         char str[] = "C++ is a case-sensitive, freeform programming language. This chapter pre sents the lexical rules for the language.";
  12.            myBuf.data = new char[strlen(str)];
  13.            
  14. memcpy(myBuf.data, str, strlen(str));
  15.        
  16.         cout<<"myBuf.data = "<< myBuf.data<<endl;

  17.         cin.get();
  18.         return 0;
  19. }

复制代码


输出结果:
myBuf.data = C++ is a case-sensitive, freeform programming language. This chapte
r presents the lexical rules for the language.??



第二种情况:


  1. #include <iostream>
  2. #include <cstdlib>
  3. using namespace std;

  4. typedef struct
  5. {
  6.         char *data;
  7. }Buf;

  8. void allocMem(Buf &buf, const char *str)
  9. {
  10.         buf.data = new char[sizeof(str)];
  11.         memcpy(buf.data, str, sizeof(str));

  12. }

  13. int main()
  14. {
  15.         Buf myBuf;
  16.         char str[] = "C++ is a case-sensitive, freeform programming language. This chapter presents the lexical rules for the language.";
  17.         allocMem(myBuf, str);

  18.         cout<<"myBuf.data = "<< myBuf.data<<endl;

  19.         cin.get();
  20.         return 0;
  21. }

复制代码


输出结果:
myBuf.data = C++ ??1


请高手指点,什么原因导致了这种错误;如何得到想要的结果。
3ks!

[ 本帖最后由 JustUSTC 于 2006-12-28 11:04 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-12-28 11:09 |只看该作者
因为指针的sizeof是。。。,了解了吧,呵呵

论坛徽章:
0
3 [报告]
发表于 2006-12-28 11:16 |只看该作者
^_^,本来是写strlen的,写错了;
我改成strlen后,第二个程序结果是:
myBuf.data = C++ is a case-sensitive, freeform programming language. This chapte
r presents the lexical rules for the language.ACP_PATH=F:\VC6\MSDev98\Bin;F:\Mic
rosoft Visual Studio\VC98\BIN;F:\VC6\TOOLS;F:\VC6\TOOLS\WINNT;G:\Professional So
ftware\Perl\Active perl\bin;C:\WINNT\SYSTEM32;C:\WINNT;C:\WINNT\System32\Wbem;c:
\Program Files\Microsoft SQL Server\90\Tools\binn;G:\Professional Software\java\
bin;C:\WINNT\Microsoft.NET\Framework\v2.0.50727;d:\program\matlab\bin\win32;G:\P
rofessional Software\V6\MSDev98\Bin;G:\Professional Software\V6\Tools;f:\VC6\bin


怎么回事?

论坛徽章:
0
4 [报告]
发表于 2006-12-28 11:18 |只看该作者
^_^,又行了。

论坛徽章:
0
5 [报告]
发表于 2006-12-28 11:22 |只看该作者
Buf 最好大一个字节,存储字符串结束标志'\0',否则打印出来的内容可能不稳定

论坛徽章:
0
6 [报告]
发表于 2006-12-28 11:23 |只看该作者

原因就是开辟的空间大小不一致

1> strlen 算的是字符串大小,严格的说不是空间大小 开辟的空间大小应该是 (strlen(str) + 1)*sizeof(char)
2> 第二个程序开辟空间是new的大小为sizeof(str) str是一个const char * 只占4个字节
至于输出c++ 1 那是因为字符串必须用'\0'结尾(ASIC c) ,data指针指向了堆的首地址,不提供'\0'则输出不正常(如果将标准输入输出更改为二进制输出,那么'\0'就没关系了,好久没用c++了,说错了欢迎拍砖)

可能我说的不够书面,但是你可以测试一下,输出sizeof(str) 和 strlen(str) 的大小
c的堆申请:

    char str[] = "kaokaokaokaokao";
  char *data = (char *) malloc( (strlen(str) + 1 ) * sizeof(char) );
memset(data,0x0,(strlen(str) + 1 ) * sizeof(char));
strncpy(data,str,strlen(str);

C++则将malloc 换成new即可




原帖由 JustUSTC 于 2006-12-28 11:02 发表
程序:
第一种情况:
[code]
#include <iostream>
#include <cstdlib>
using namespace std;

typedef struct
{
        char *data;
}Buf;

int main()
{
        Buf myBuf;
        char str[] = " ...

论坛徽章:
0
7 [报告]
发表于 2006-12-28 11:27 |只看该作者
第二个问题我猜是你的memcpy不保证在buffer size够的情况下帮你加上字符串结束符,所以buffer内的未被覆盖的东东就被输出流输出出来了。字符串操作为什么要用memcpy呢,呵呵

论坛徽章:
0
8 [报告]
发表于 2006-12-28 15:36 |只看该作者
指针和数组名的区别。

论坛徽章:
0
9 [报告]
发表于 2006-12-28 18:25 |只看该作者
原帖由 JustUSTC 于 2006-12-28 11:16 发表
... ACP_PATH=F:\VC6\MSDev98\Bin;F:\Mic
rosoft Visual Studio\VC98\BIN;F:\VC6\TOOLS;F:\VC6\TOOLS\WINNT;G:\Professional So
ftware\Perl\Active perl\bin;C:\WINNT\SYSTEM32;C:\WINNT;C:\WINNT\System32\Wbem;c:
\Program Files\Microsoft SQL Server\90\Tools\binn;G:\Professional Software\java\
bin;C:\WINNT\Microsoft.NET\Framework\v2.0.50727;d:\program\matlab\bin\win32;G:\P
rofessional Software\V6\MSDev98\Bin;G:\Professional Software\V6\Tools;f:\VC6\bin


进程地址空间里的东西……具体放在哪儿,和操作系统的内存管理,以及 C 库中的分配算法有关。或许这里正好有 sizeof(char *) 个字节的未分配空间,然后就放在了这里,结果造成重叠。

你改写一下,把 strlen() 的结果传给 allocMem,用来给 malloc 提供参数,就行了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP