void GetDesJSharp(char src[], char key[], LPTSTR des, bool EnDe)
{
char* buf = new char[256];
char* bufout =new char[256];
ZeroMemory(buf,256);
ZeroMemory(bufout,256);
if(EnDe)
{
buf = StrToHex(src);
bufout = encrypt(buf,key,EnDe);
}
else
{
buf = encrypt(src,key,EnDe);
bufout = HexToStr(buf);
}
ZeroMemory(des,256);
memcpy(des,bufout,strlen(bufout)); //内存泄漏
//delete[] buf;
//delete[] bufout;
}
这个函数中有两个char*,当我使用delete释放内存时就出错,如果不用delete又存在内存泄漏,该怎么办?
解决方案 »
- VC如何调用用OPENCV编写的程序
- vc如何用ado提取access中某一列的数据进行图像曲线绘制
- 深入浅出MFC 第三章有关 CreateObject() 的问题
- WebBrowser如何获得源代码啊?弄了好几天了,急!
- 调试时如何去掉output窗口中的waring
- 打印时如何实现 像素与mm(毫米)之间的单位转换呢 有没有好一点的方法?THANKS
- 如何生成RTF文件?
- C++写的动态链接库是没有类的概论,这个理解是否正确
- 如何让我的程序减肥
- 请教高手——在vc中如何将程序进程从一个类的一个函数转到另一个类的protect型函数并访问其protect变量
- 如何实现图片预览
- winsock HTTP下载超时的问题?
而从函数返回的指针,是否需要delete,得看具体这个函数是否需要你detele。
另外,LPTSTR没有指示大小的参数配合,也没有地方来判断是否越界,最后这个ZeroMemory、memcpy函数都存在溢出的危险。
char* bufout =new char[256];
只给声明就行了,分配出来的内存没用上而且delete时的指针地址并非分配到的内存的地址
bufout [256]定义在栈上,不久行了,干嘛new?
StrToHex、encrypt中都没有申请内存,都是参数传入的。
void GetDesJSharp(char src[], char key[], LPTSTR des, bool EnDe)
{
//char* buf = new char[256];
//char* bufout =new char[256];
char* buf;
char* bufout;
//char buf[256];
//char bufout[256];
//ZeroMemory(buf,256);
//ZeroMemory(bufout,256);
if(EnDe)
{
buf = StrToHex(src);
bufout = encrypt(buf,key,EnDe);
}
else
{
buf = encrypt(src,key,EnDe);
bufout = HexToStr(buf);
}
//ZeroMemory(des,256);
memcpy(des,bufout,strlen(bufout)); //内存泄漏
//delete[] buf;
//delete[] bufout;
}
哈哈,解决了。
内存申请的问题都主存函数的外部,也就是调用都申请内存。
.............
有点高兴。另外,LPTSTR没有指示大小的参数配合,也没有地方来判断是否越界,最后这个ZeroMemory、memcpy函数都存在溢出的危险。现在就剩下memcpy越界存在溢出的可能,暂时放在调用时统一约定长度,这个与StrToHex、encrypt也有关。
StrToHex()没有申请内存;
encrypt()中得时申请的内存都在函数返回前销毁了;
StrToHex()返回的指针是传入的参数;
encrypt()返回的指针是个类中共用的char ch[256];
这个程序问题确实很多,待我再研究研究
改改,呵呵
我按你所说的方法改了整个函数及类,现在在C++ 环境中调用Dll没有问题,可是如果用C#项目调用就不行了。下面是出错信息:未处理的“System.AccessViolationException”类型的异常出现在 DLLTESTC.exe 中。其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
----------------------------------------------------------------------------
把你的代码贴出来。可能的情况:
1. 你的类没有修改好,内部有问题没有处理,比如越界
2. 你在调用它时,缓冲区不正确,指向了不可写的内存区
3. 你在调用 它时,使用了野指针
4. unicode造成了越界,而你没有注意到。即你的dll使用了unicode,而C#使用了ansi,所以当你传入了认为是8个字节的缓冲区时,在dll中可能认为是8个字符(16个字节),此时你拷贝进去超过8个字节的内容时越界
5. 你拷贝操作时的源字符串缓冲区没有以'\0'结尾致使其后面带了很长的字符串造成了越界
准备自己再检查你所说的几点。
谢谢!
{
ZeroMemory(pwout,STR_LEN);//返回值初始化 STR_LEN=260
char tt[STR_LEN];
....... strcpy_s(p_str, tt);//这行不出错,
strcpy_s(pwout, tt);//这行编译能不过,说不能用2个参数
strcpy_s(p_str,strlen(tt), tt);//这个地方变换多种格试置换也不行,L(Buffer too small...
strcpy_s(p_str,_countof(tt), tt);//编译没有问题,C#调用时不能用string作参数
return p_str;//
}
好象用strcpy还只有警告而不出错。另:出错类型与C#调用时的参数的数据类型关系很大,string出错,StringBiulder、IntPtr不出错,BSTR好象也能用
{
ZeroMemory(pwout,STR_LEN);//返回值初始化 STR_LEN=260
char tt[STR_LEN];
.......
----------------------------------------------------------------------
我觉得这样写不大好,习惯于这样写:
char* encrypt(char *pw,char *key,bool jiami,char *pwout, long lenoutbuf)
{
ZeroMemory(pwout,lenoutbuf);//返回值初始化 STR_LEN=260
char *ptt = new char[lenoutbuf];
.......另外,strcpy_s()要求具体的参数长度,而且这样修改之后,应该就可以编译通过了
问题就在这个上面,第三个参数用const char*或char []可以,用char*不行;
第二个参数用_countof()获取整个数组的元素可以,用strlen或其他int变量包括常量都可能出错;
可是_countof是整个数组元素个数啊,会影响效率吧?通过几天的反复测试,觉得问题的关键是:
1、中间的Buffer用什么类型过度;
2、传出参数时用什么函数,memcpy还是strcpy,strcpy是肯定没有出错,但有个编译警告,memcpy和strcpy_s都有出错的情况;
这算不算是VS2005的一个Bug?我觉得函数strcpy_s既然有参数_DstSize,就应该用它检查数据的正确与否,当_DstSize,小于_Dst的大小(长度)时,应该版对_DstSize+1置'\0'。
{
char* buf = NULL;//new char[256];
char* bufout =NULL;//new char[256];
//ZeroMemory(buf,256);
//ZeroMemory(bufout,256);
if(EnDe)
{
buf = StrToHex(src);//查看这个函数的调用规约 bufout = encrypt(buf,key,EnDe);//查看这个函数的调用规约 }
else
{
buf = encrypt(src,key,EnDe);//查看这个函数的调用规约 bufout = HexToStr(buf);//查看这个函数的调用规约 }
ZeroMemory(des,256);
memcpy(des,bufout,strlen(bufout)); //内存泄漏
//delete[] buf;
//delete[] bufout;
}
我编程是肯定要考虑目标参数能不能容纳下源,虽然这个错误是会出,但这不应该是开发平台解决的问题,它应该解决我们合理的参数不出错。哎,不懂英语,不然早就发现问题并解决了
鉴于大家的热心,本贴再加100分,然后结贴。