函数内new申请一个不定值的内存,在函数外部怎么释放

刨根问底不怕事 2017-01-23 09:23:19
加精
unsigned char *cmdToint(string cmd)
{
long len = cmd.length() / 2;
unsigned char temp[2];
char *ccmd =(char *) cmd.c_str();
unsigned char *command = new unsigned char[len + 1];
unsigned char *commandTmp = new unsigned char[len * 2 + 1];
strcpy((char *)commandTmp, ccmd);
for (int i = 0; i < len; ++i)
{
temp[0] = commandTmp[i * 2];
temp[1] = commandTmp[i * 2 + 1];

sscanf_s((char*)temp,"%x",&command[i]);//sscanf会先将字符串转换为对应的16进制整数
}
delete []commandTmp;
return command;
}








	string scmd = "80E006000400000200";
unsigned char *cmd=cmdToint(scmd);
unsigned char *rec=new unsigned char[40];
senddata(hdll)(handle, 1, 9, cmd, rec);
delete []cmd;
printf("清卡返回值:%x%x\n", rec[0], rec[1]);





这样释放会错误,请问要怎么释放,函数内new申请一个不定值的内存,在函数外部怎么释放
...全文
7423 41 打赏 收藏 转发到动态 举报
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-01-18
  • 打赏
  • 举报
回复
delete Operator C++ Specific [::] delete pointer [::] delete [ ] pointer The delete keyword deallocates a block of memory. The argument pointer must point to a block of memory previously allocated by the new operator. If pointer points to an array, place empty brackets before pointer. Example In the following example, the block of memory pointed to by pFile is deallocated: // Example of the delete operator CATCH_ALL(e) { ar.Close(); delete pFile; THROW_LAST(); } END_CATCH_ALL END C++ Specific
真相重于对错 2018-01-17
  • 打赏
  • 举报
回复
new 以后,你不能修改那个指针,比如重新把它指向一个新的地址!
rjw_999 2018-01-17
  • 打赏
  • 举报
回复
引用 17 楼 JiLuoXingRen 的回复:
一般遇到函数内分配,函数外释放的问题,都应该采用预分配的方式,要求函数的调用者分配好结果缓冲区再把指针传进来,你的结果写进去。因为你无法保证调用这个函数的人(尤其是一个项目不止你一个人在写的时候)知道要且会释放,万一他忘了或根本不知道要释放呢。例如:

// 先分配好,再
void cmdToint(string cmd, unsigned char * result)
{
    // ……
}

void main()
{
    strng s;
    // 主调方先分配好内存
    long len = s.length() / 2;
    unsigned char *resbuf  = new  unsigned char[len + 1];
    // 再来调用函数
    cmdToint(s, resbuf);
    // 使用resbuf,之后自然会知道要释放,他忘了是他的责任
    delete[] resbuf;
}
你可能会说主调方不知道需要多大的空间,那么你可以再提供一个函数返回需要的空间大小

// 先分配好,再
void cmdToint(string cmd, unsigned char * result)
{
    // ……
}

// 返回需要的空间大小
int ctiSizeNeed(string cmd)
{
    return cmd.length() / 2;
}

void main()
{
    strng s;
    // 调用ctiSizeNeed获取对于s函数返回的结果需要多大的空间,先分配好内存
    unsigned char *resbuf  = new  unsigned char[ctiSizeNeed(s)];
    // 再来调用函数
    cmdToint(s, resbuf);
    // 使用resbuf,之后自然会知道要释放,他忘了是他的责任
    delete[] resbuf;
}
是这么回事
他笑他自己 2017-10-27
  • 打赏
  • 举报
回复
函数结束除了你申请的动态空间,其他的都被销毁,你用来指向这片空间的指针一样被销毁。除非你的指针是全局的
bdakghyf 2017-03-08
  • 打赏
  • 举报
回复
亟待解决的你的肌肤你疯狂烦恼苦闷
linux_hsylar 2017-03-06
  • 打赏
  • 举报
回复
二级指针感觉挺好
罗耗子 2017-03-06
  • 打赏
  • 举报
回复
新手都不喜欢memset
worldy 2017-03-02
  • 打赏
  • 举报
回复
unsigned char *cmdToint(string cmd) { long len = cmd.length() / 2; unsigned char temp[2]; char *ccmd =(char *) cmd.c_str(); unsigned char *command = new unsigned char[len + 1]; unsigned char *commandTmp = new unsigned char[len * 2 + 1]; strcpy((char *)commandTmp, ccmd); //这里有问题,ccmd没有初始化,可能是一块随机值,并且没有包含0值得单元,复制会超出申请的范围 for (int i = 0; i < len; ++i) { temp[0] = commandTmp[i * 2]; temp[1] = commandTmp[i * 2 + 1]; sscanf_s((char*)temp,"%x",&command[i]);//sscanf会先将字符串转换为对应的16进制整数 } delete []commandTmp;//这里不会有问题,但是不是类对象,没有释构函数,不需要[] return command; } 其他的说法都是扯淡
yugossb 2017-03-02
  • 打赏
  • 举报
回复
Nice!!!
zhujinqiang 2017-02-28
  • 打赏
  • 举报
回复
twintiger 2017-02-22
  • 打赏
  • 举报
回复
引用 23 楼 a393062456 的回复:
今天我用自己的程序调了下,我的代码设这样的
BYTE data[6] = { 0 };
	int start = 0;
	int n = 0;
	if (n = recvSocke->Receive(data, 6))
	{
		CString header;
		header.Format("%02X%02X%02X", data[0], data[1], data[2]);

		UINT data_len = 0;
		CString hex;
		hex.Format("%02X%02X", data[3], data[4]);
		data_len = Hex2Ten(hex);

		BYTE *allData = new BYTE[data_len + 56];
		while (n < data_len + 7)
		{
			memcpy(allData + start, data, n);
			start = n;
			n += recvSocke->Receive(data, 6);
		}
		memcpy(allData + start, data, n);
		delete [] allData;
	}
客户端发过来的数据包总长度为51字节,程序里面解析出来的可用数据长度data_len为44。要接收完我这个数据包,其实只要申请51个字节长度的内存就可以了,开始我用的是new BYTE[data_len+7],结果在delete的时候果断出错。然后自己一步步调试,发现出现的是heap corruption,堆破坏,然后问了下同学,他说可能是申请的内存小了(但是在delete之前,我整个数据包都memcpy进去了啊,如果申请的内存小了,memcpy的时候怎么不报错误呢?)。然后我修改成50,也就是总共94个字节,这比我整个数据包的长度都长很多了,然后调试,发现还是出错,但这次的错误原因是critical error detected。于是又百度了下,http://www.cnblogs.com/mavaL/archive/2012/12/30/2839968.html这里提了下出错原因。好吧,我于是又加大申请的内存大小。直接改成data_len+100,就是144,比我整个数据包的两倍还大了。然后编译调试运行,发现一切正常。至于为什么会这样,正在研究中
实际上是一个小错误,你while里面n是累计长度,实际读到的是是6个字节,相当于每次memcpy拷贝6,12,18,24. 正确的写法是 start += n; n = recvSocke->Receive(data, 6); 你不妨while结束打印start和n看看是多少,是51个字节?
  • 打赏
  • 举报
回复
Pingo520 2017-02-22
  • 打赏
  • 举报
回复
引用 30 楼 twintiger 的回复:
[quote=引用 23 楼 a393062456 的回复:] 今天我用自己的程序调了下,我的代码设这样的
BYTE data[6] = { 0 };
	int start = 0;
	int n = 0;
	if (n = recvSocke->Receive(data, 6))
	{
		CString header;
		header.Format("%02X%02X%02X", data[0], data[1], data[2]);

		UINT data_len = 0;
		CString hex;
		hex.Format("%02X%02X", data[3], data[4]);
		data_len = Hex2Ten(hex);

		BYTE *allData = new BYTE[data_len + 56];
		while (n < data_len + 7)
		{
			memcpy(allData + start, data, n);
			start = n;
			n += recvSocke->Receive(data, 6);
		}
		memcpy(allData + start, data, n);
		delete [] allData;
	}
客户端发过来的数据包总长度为51字节,程序里面解析出来的可用数据长度data_len为44。要接收完我这个数据包,其实只要申请51个字节长度的内存就可以了,开始我用的是new BYTE[data_len+7],结果在delete的时候果断出错。然后自己一步步调试,发现出现的是heap corruption,堆破坏,然后问了下同学,他说可能是申请的内存小了(但是在delete之前,我整个数据包都memcpy进去了啊,如果申请的内存小了,memcpy的时候怎么不报错误呢?)。然后我修改成50,也就是总共94个字节,这比我整个数据包的长度都长很多了,然后调试,发现还是出错,但这次的错误原因是critical error detected。于是又百度了下,http://www.cnblogs.com/mavaL/archive/2012/12/30/2839968.html这里提了下出错原因。好吧,我于是又加大申请的内存大小。直接改成data_len+100,就是144,比我整个数据包的两倍还大了。然后编译调试运行,发现一切正常。至于为什么会这样,正在研究中
实际上是一个小错误,你while里面n是累计长度,实际读到的是是6个字节,相当于每次memcpy拷贝6,12,18,24. 正确的写法是 start += n; n = recvSocke->Receive(data, 6); 你不妨while结束打印start和n看看是多少,是51个字节? [/quote] 嗯,已经解决了,自己傻,犯的低级错误
副组长 2017-02-21
  • 打赏
  • 举报
回复
这样申请内存是非常正常的用法,所谓的谁申请谁释放那是糊弄新手呢。
Pingo520 2017-02-21
  • 打赏
  • 举报
回复
引用 25 楼 bravery36 的回复:
while (n < data_len + 7) { memcpy(allData + start, data, n); start = n; n += recvSocke->Receive(data, 6); } 这里逻辑问题太大了,data长度是6啊,你memcpy n..........
嗯嗯,自己犯傻了,低级错误
Pingo520 2017-02-21
  • 打赏
  • 举报
回复
我那个我弄明白了,自己犯了个低级错误,循环里面n累加了。 你的这个10楼说的是对的,由于sscanf_s引起的,你把这句注释掉绝对没问题。
hugh_z 2017-02-20
  • 打赏
  • 举报
回复
66666666
xiaoxiangqing 2017-02-20
  • 打赏
  • 举报
回复
可以把指针传到函数里
bravery36 2017-02-20
  • 打赏
  • 举报
回复
你处理总长度和单个recv的长度时用混了,再加个变量吧。
bravery36 2017-02-20
  • 打赏
  • 举报
回复
while (n < data_len + 7) { memcpy(allData + start, data, n); start = n; n += recvSocke->Receive(data, 6); } 这里逻辑问题太大了,data长度是6啊,你memcpy n..........
加载更多回复(21)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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