C-安全地解析和发送大量无止境的字符串
我在C方面没有太多经验 我有一个小的C程序,它连接到一个几乎无限的文本流(25Mb/s) 我想用zeromq将字符串的每一行作为单独的消息发送 因此,我将每秒发送数千条消息,在发送每条消息之前,我想处理通过套接字发送的字符串: 假设我从以下几点开始:C-安全地解析和发送大量无止境的字符串,c,zeromq,C,Zeromq,我在C方面没有太多经验 我有一个小的C程序,它连接到一个几乎无限的文本流(25Mb/s) 我想用zeromq将字符串的每一行作为单独的消息发送 因此,我将每秒发送数千条消息,在发送每条消息之前,我想处理通过套接字发送的字符串: 假设我从以下几点开始: Quote {0.0.0.0} XXX <1>A<2>B<3>C 这样行吗 如下更改您的main: int main(void) { const char *a = "Quote {0.0.0.0} X
Quote {0.0.0.0} XXX <1>A<2>B<3>C
这样行吗 如下更改您的
main
:
int main(void)
{
const char *a = "Quote {0.0.0.0} XXX <1>A<2>B<3>C";
char *buff = parse(a);
SEND_MESSAGE(buff);
free(buff);
return 0;
}
正如对问题的评论所提到的,最好将output
声明为全局变量(因此将前一行置于parse
之外),并将free
声明在程序的最末端(输入流字符串的循环之外)。这确实使程序更快。如果您知道(或可以特别确定)每个第一个、第二个、第三个和第四个的最大大小,只需为每个使用固定大小的缓冲区,就可以消除内存泄漏的所有可能性。你说你的25米/秒的文本被分成了几行,所以你大概是在使用一个面向行的输入函数(例如fgets
或getline
)从流中读取。在这种情况下,您也可以使用最大行长度(X4)来确保您的固定缓冲区足够
您正在使用空格
作为分隔符将标记化为第一个
、第二个
、第三个
和第四个
,那么为什么不使用sscanf
?如果要使用parse
函数,只需将缓冲区作为参数传递即可
如果您可以确定一个最大值,并在空间上标记,您可以做一些简单的事情,如:
#include <stdio.h>
#define MAXC 1024
int main(void)
{
const char *a = "Quote {0.0.0.0} XXX <1>A<2>B<3>C";
char first[MAXC] = "",
second[MAXC] = "",
third[MAXC] = "",
fourth[MAXC] = "";
/* read a line from the stream and simply call sscanf */
if (sscanf (a, " %s %s %s %s", first, second, third, fourth) == 4)
printf ("%s %s %s\n", third, first, fourth);
return 0;
}
(这样做的副作用是大大简化您的代码,并可能大大加快代码的速度)
如果您不能满怀信心地确定最大大小,那么您将陷入malloc
/free
(或者使用POSIXgetline
并让它处理分配)的开销中。不。您不能在返回后释放。事实上,您不能将任何语句放在return
之后,因为它不会被执行。如果这是一项大型重复性任务,请考虑完全删除动态分配。使用一个静态分配的缓冲区,大到足以容纳最坏的情况,将更快得多。考虑使用<代码>墙>代码>编译器选项,它会帮助您避免坏的。practice@Lundin听起来是个好主意。这绝对是一项庞大的重复性任务(实际目的是无限的)。不过,我不确定这将如何运作。消息(输入)有一个最大大小。那么,我应该创建一个大约这个大小(或更大?)的缓冲区来创建和存储解析后的字符串,然后清除它并重复吗?你能给我举个例子吗?@在解析输入字符串的同时,你会一直把它复制到静态缓冲区。然后发送缓冲区的内容。在下一次迭代中,您只需覆盖缓冲区的内容-空终止将确保只使用有效数据。这并不能回答问题的最重要部分:循环@JacekCz中没有错误。他问了内存泄漏的问题,我的解决方案确实回答了。同意(部分同意)。问题是在基本的层面上,在这个时刻和好的,快的,无铅的环路无关。只在描述中谢谢你!这非常有帮助/有启发性。当然,很乐意帮忙。有时候(大多数时候)亲吻哲学是你最好的选择。
int main(void)
{
const char *a = "Quote {0.0.0.0} XXX <1>A<2>B<3>C";
char *buff = parse(a);
SEND_MESSAGE(buff);
free(buff);
return 0;
}
char *output = malloc(1024); //for example
#include <stdio.h>
#define MAXC 1024
int main(void)
{
const char *a = "Quote {0.0.0.0} XXX <1>A<2>B<3>C";
char first[MAXC] = "",
second[MAXC] = "",
third[MAXC] = "",
fourth[MAXC] = "";
/* read a line from the stream and simply call sscanf */
if (sscanf (a, " %s %s %s %s", first, second, third, fourth) == 4)
printf ("%s %s %s\n", third, first, fourth);
return 0;
}
$ ./bin/staticbuf
XXX Quote <1>A<2>B<3>C