【发布时间】:2016-07-23 07:01:05
【问题描述】:
我想接收来自服务器的消息响应,所以我编写了下面的函数:
char * receive_response(SSL *ssl, BIO *outbio) {
int bytes;
int received = 0;
char *resp;
resp = (char *) malloc(4096*sizeof(char));
bytes = SSL_read(ssl, resp, 4096);
resp[strlen(resp)] = '\0';
if (bytes < 0) {
BIO_printf(outbio, "\nError reading...\n");
exit(1);
}
received += bytes;
BIO_printf(outbio, "Received...%d bytes\n", received);
BIO_printf(outbio, "%s", resp);
BIO_printf(outbio, "Receive DONE\n");
return resp;
}
但是当我运行它时出现错误:malloc():memory corruption。 奇怪的是,当我在 main.js 中第二次调用此函数时会发生这种情况。第一次没问题。请帮助我理解它。
【问题讨论】:
-
memset(resp, 0, sizeof(resp));是错误的...sizeof(resp)是指针的大小,而不是您分配的块的大小...尽管它可能无关紧要。另外,strlen()使用 null 终止符来确定字符串的结尾在哪里,所以在 null 还没有添加的情况下你不能使用它。 -
对不起,我一开始将 resp 声明为数组时使用它。我删了它。而且,strlen(),谢谢你,我的错。但是错误仍然存在。
-
为空终止符分配一个额外的字节(4097字节,如果你读到4096),并使用
resp[bytes] = '\0';而不是resp[strlen(resp)] = '\0';(在检查bytes是> = 0之后) .使用strlen()来确定将空终止符放在哪里是一个错误,因为如果空终止符还不存在,strlen()将无法正常工作。另外,你什么时候释放你的缓冲区? -
内存损坏错误的问题在于,您通常不会看到它们,直到您将事情搞砸后下一次尝试分配。查看问题错误之前发生的所有代码。如果需要,在战略点插入虚拟分配以尝试缩小范围。根据您的平台,可能有一种方法可以验证堆,这也有助于缩小问题范围。 Valgrind 也可能是一种选择。
-
@Dmitri 我将其更改为 resp[bytes] = '/0'。在我第一次调用函数时,字节的值(实际读取的字节数)小于 4KB,所以我认为我不需要释放缓冲区。函数完成后,所有变量都将是空闲的,对吧?
标签: c sockets openssl malloc httpresponse