C发送方法空闲缓冲区吗?

时间:2011-04-09 13:22:00

标签: c free send

我对C的发送方法有疑问。

int send (int socket, void *buffer, size_t size, int flags);

我的代码:

char *buffer = (char *)malloc(100*sizeof(char));
send(s, buffer, 100*sizeof(char), MSG_NOSIGNAL);

现在我想知道我是否应该自己释放缓冲区,还是将send方法释放出来?

我释放缓冲区的代码:

char *buffer = (char *)malloc(100*sizeof(char));
send(s, buffer, 100*sizeof(char), MSG_NOSIGNAL);
free(buffer);

当我看到错误时,我认为我很快就释放了缓冲区,而send方法仍在使用内存。

让我知道。

5 个答案:

答案 0 :(得分:6)

send没有释放缓冲区。你需要释放它。除了它不是那样设计的事实(套接字函数独立于堆函数),send实际上并不“知道”是否应该释放内存,因为它可能是指向分配的块的中间的指针内存或它可能是堆栈数据的指针。

在发送调用之后立即释放缓冲区应该是“安全的”,因为该函数已将数据复制到其自己的内部缓冲区。您显示的代码不会导致损坏问题(尽管我怀疑涉及更多代码,因为缓冲区未如图所示初始化)。堆可能在进程的早期被破坏,并且直到稍后才导致异常(例如,发送后的空闲)。

send的返回值表示成功发送的字节数(尽管未必成功传送)。因此,虽然释放它是“安全的”,但如果不是全部发送,您将丢失未发送的数据。如果没有发送整个缓冲区,则需要再次使用剩余金额调用send。

答案 1 :(得分:1)

free调用返回后,您可以send缓冲区,注意以下内容:

  • 可能尚未发送整个缓冲区。
  • 该调用返回内核已复制到其自己的缓冲区中的字节数。其余的你应该保留。

此代码可以帮助您了解正在发生的事情,但绝不应该基于此:

char *buf; // sizeof(*buf) must be 1 for pointer arithmetic
ssize_t sent = send(fd, buf, len, 0);
if (sent != -1) { // no error
    // move the unsent bytes to the start of the buffer
    memmove(buf, buf + sent, len - sent);
    // resize the buffer to fit the left over bytes
    buf = realloc(buf, len - sent);
}

答案 2 :(得分:0)

send()不释放缓冲区。如果你有双重免费问题,你应该看看你可以放在哪里,并检查你是如何到达那里的。

答案 3 :(得分:0)

一般来说,如果api函数释放缓冲区,那将是非常不寻常的。我所知道的唯一一个释放缓冲区的函数是“免费”......

有时,函数会分配使用后必须释放的内存,例如: strdup

有些功能,使用后无法直接释放缓冲区。例如,在.Net中,如果仍然在位图包装器中使用它,则不能处置位图的数据指针。

答案 4 :(得分:0)

从你的描述中听起来好像你的代码在释放后使用了一个指针。有很好的,可靠的方法来捕捉这类问题,然后有快速的黑客攻击。这是一个快速黑客:

#define free(p) do { (free)(p); p=(void*)1; } while (0)

这个宏,您希望包含在头文件或项目的第一行,将您的调用替换为free,以便:

  1. 内存仍为free(),符号(free)(p)强制C编译器将(free)评估为函数符号,而不是宏扩展。
  2. 指针设置为无法访问的值,1。未使用值NULL(0),因为free()如果通过NULL则不会抱怨。传递“指针值”1会触发错误报告。
  3. 您可能会发现在使用此宏之后,您的代码已经解除了过时的指针。一旦你有free'内存,指向它的指针将指向相同的内存,并暂时指向内存中的相同值 - 直到第二次使用该内存擦除这些值。因此,您的程序可能能够使用过时指针运行几行。 <!1}}当它变为陈旧时,将每个指针都更改为将立即捕捉到它。