【发布时间】:2014-12-12 07:45:02
【问题描述】:
我目前正在编写一段代码,该代码将通过以太网将一些 XML 数据作为字符串发送。应该首先构造数据,以便将其发送到套接字。我正在使用 STM32F4xx 类型的微控制器并使用 IAR EWARM 嵌入式开发环境。
我一直在使用以下功能:
char* concat(char *s1, char *s2)
{
size_t len1 = strlen(s1);
size_t len2 = strlen(s2);
char *result = malloc(len1+len2+1);//+1 for the zero-terminator
//in real code you would check for errors in malloc here
memcpy(result, s1, len1);
memcpy(result+len1, s2, len2+1);//+1 to copy the null-terminator
return result;
}
char* data = concat("<data>\n<items>\n<radar x=\"", "1");
data = concat(data, "\"></radar>\n<radar v=\"");
data = concat(data, "1");
data = concat(data, "\"></radar>\n</items>\n</data>");
len = strlen(data);
Socket_Send(data,len);
以太网服务器输出结果如下:
Send:(09:41:17) alive
Rec:(09:41:17)<data>
<items>
<radar x="1"></radar>
<radar v="1"></radar>
</items>
</data>
Send:(09:41:18) alive
Rec:(09:41:18)<data>
<items>
<radar x="1"></radar>
<radar v="1"></radar>
</items>
</data>
Send:(09:41:18) alive
Rec:(09:41:18)<data>
它正确发送数据 2 次,然后只写入 6 个字符。我该如何解决?任何帮助是极大的赞赏。提前谢谢..
编辑 1: 建议代码:
data = concat("<data>\n<items>\n<radar x=\"", "1");
char *tmp = data;
data = concat(data, "\"></radar>\n<radar v=\"");
free(tmp);
data = concat(data, "1");
data = concat(data, "\"></radar>\n</items>\n</data>");
len = strlen(data);
输出:
Send:(09:51:38) alive
Rec:(09:51:38)<data>
<items>
<radar x="1"></radar>
<radar v="1"></radar>
</items>
</data>
Send:(09:51:40) alive
Rec:(09:51:40)<data>
<items>
<radar x="1"></radar>
<radar v="1"></radar>
</items>
</data>
Send:(09:51:44) alive
Rec:(09:51:44)<data>
<items>
<radar x="1"></radar>
<radar v="1"></radar>
</items>
</data>
Send:(09:51:44) alive
Rec:(09:51:44)8 ¹Õ"></radar>
</items>
</data>
Send:(09:51:44) alive
Rec:(09:51:44)8 ¹Õ1"></radar>
</items>
</data>
Send:(09:51:45) alive
Rec:(09:51:45)8 ¹Õ1"></radar>
</items>
</data>
Send:(09:51:45) alive
Rec:(09:51:45)8 ¹Õ
Send:(09:51:45) alive
Rec:(09:51:45)8 ¹Õ
Send:(09:51:46) alive
Rec:(09:51:46)8 ¹Õ
Send:(09:51:46) alive
Rec:(09:51:46)8 ¹Õ
编辑 2(糟糕的解决方案):
char* data;
char* data1;
char* data2;
char* data3;
data1 = concat("<data>\n<items>\n<radar x=\"", "1");
data2 = concat(data1, "\"></radar>\n<radar v=\"");
free(data1);
data3 = concat(data2, "1");
free(data2);
data = concat(data3, "\"></radar>\n</items>\n</data>");
free(data3);
len = strlen(data);
Socket_Send(data,len);
free(data);
编辑 3(已解决):
当 XML 中的标签数量增加时,mem 泄漏按预期发生。正如人们所建议的那样,我尝试了 strcat 并且成功了。但是 strcpy 在我的编译器中不起作用。我强烈建议任何有同样问题的人使用 strcat。
【问题讨论】:
-
我强烈建议将内存分配与算法分开。可悲的是,经验告诉我,如果程序在某处有一个函数,它返回一个指向动态分配内存的指针,几乎可以肯定会有内存泄漏。
-
旁注:使用
strcpy,strcat而不是memcpy,memcpy。 -
旁注#2:似乎不需要所有运行时串联。您所有的字符串都是常量,因此您不妨静态分配一个字符串。除了额外的安全性(通过避免动态内存分配/释放来实现)之外,您还将提高运行时性能,此外 - 保持它不变,因为在整个程序执行过程中字符串将驻留在相同的内存地址(没有意外的缓存影响等)。恒定的执行时间通常被认为是嵌入式系统中的一个关键方面。
-
该实现已经提到了一个严重的内存泄漏问题,但是由于here 讨论的原因,字符串连接的方法可能会产生严重的性能影响 - 除了性能影响和不确定性之外首先是动态内存分配。