继续调用malloc()和free()有多糟糕?

cap*_*him 19 c malloc free network-programming packets

我正在发送一个文本文件 - 客户端 - 服务器将文本分解为每个512字节的数据包,但是一些数据包包含的文本小于最大大小所以在接收每个数据包的服务器端我正在调用malloc()再次构建一个字符串这是一种不好的做法吗?保持一个适合最大长度的工作缓冲区并保持迭代,复制和覆盖它的值更好吗?

好吧@nm这里是代码,这个if是在select()唤醒的for(;;)循环里面

if(nbytes==2) {
            packet_size=unpack_short(short_buf);
            printf("packet size is %d\n",packet_size);
            receive_packet(i,packet_size,&buffer);
            printf("packet=%s\n",buffer);
            free(buffer);
}
//and here is receive_packet() function 
int receive_packet(int fd,int p_len,char **string) {
 *string = (char *)malloc(p_len-2); // 2 bytes for saving the length    
 char *i=*string;   
 int temp;
 int total=0;
 int remaining=p_len-2;
 while(remaining>0) {
     //printf("remaining=%d\n",remaining);
     temp = recv(fd,*string,remaining,0);
     total+=temp;
     remaining=(p_len-2)-total;
     (*string) += temp;
 }
 *string=i;
 return 0;
 }
Run Code Online (Sandbox Code Playgroud)

R..*_*R.. 17

在您的示例中,您的函数已经包含一个系统调用,因此malloc/ 的相对成本free几乎无法衡量.在我的系统上,malloc/ free"往返"平均约300个周期,最便宜的系统调用(获得当前时间,pid等)至少花费2500个周期.预计recv很容易花费10倍,在这种情况下,分配/释放内存的成本最多约为此操作总成本的1%.

当然,确切的时间会有所不同,但粗略的数量级应该在各个系统中相当不变.我甚至不会考虑删除malloc/ free作为优化,除了纯粹用户空间的函数.在没有动态分配的情况下实际上更有价值的是在不应该有故障情况的操作中 - 这里的价值在于您通过不必担心失败时要做什么来简化强化代码malloc.

  • 使用初始化为NULL的10-100分配数组和随机大小的malloc/free随机分配时隙将是更好的测试. (3认同)
  • 当不需要从操作系统映射新内存时,我正在计时 `free(malloc(1));` (在 Linux/glibc/i686 上,使用 `rdtsc` 进行测量),只需重用现有的先前释放的内存。这几乎总是常见的情况。您唯一应该担心从操作系统获取新内存的时间是在实时编程中,您关心任何操作的**最坏情况**延迟,而不是程序的整体运行时间。 (2认同)

use*_*902 7

调用malloc和free会产生开销.必须从堆中分配一个块并将其标记为正在使用中,当你释放出来的时候.不知道您使用的操作系统或编译器,这可能在c库或OS内存管理级别.由于你正在做很多mallocs和释放,你可能会破坏你的堆,你可能没有足够的连续可用内存在别处做malloc.如果您只能分配一个缓冲区并继续重用它,那么通常会更快并且堆碎片的危险性更小.

  • 如果他一次又一次地分配和释放一个固定大小的块,他几乎肯定不会破坏任何东西.(这并不意味着没有开销......但在这种情况下,碎片可能不是导致它的原因.) (3认同)