【问题标题】:Error malloc(): memory corruption错误 malloc():内存损坏
【发布时间】: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


【解决方案1】:

你的字符串还没有以'\0' 结束,所以你不能在上面调用strlen

char * receive_response(SSL *ssl, BIO *outbio) {
  int bytes;
  int received = 0;
  char *resp;
  // add one extra room if 4096 bytes are effectivly got
  resp = malloc(4096+1);
  if (NULL == resp)
  { 
      perror("malloc");
      exit(1);
  }
  bytes = SSL_read(ssl, resp, 4096);
  if (bytes < 0) {
      BIO_printf(outbio, "\nError reading...\n");
      exit(1);
  }
  resp[bytes] = '\0';
  received += bytes;
  BIO_printf(outbio, "Received...%d bytes\n", received);
  BIO_printf(outbio, "%s", resp);
  BIO_printf(outbio, "Receive DONE\n");
  return resp;
}

另一种解决方案可能是调用calloc 而不是malloc...

【讨论】:

  • 他还需要确保他不会将数据读入缓冲区的最后一个字节,以确保'\0'有空间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多