C++ 内存通过new[]泄漏,但从未调用new

C++ 内存通过new[]泄漏,但从未调用new,c++,memory-leaks,new-operator,valgrind,fread,C++,Memory Leaks,New Operator,Valgrind,Fread,我从以下函数中得到内存泄漏: int ReadWrite(int socket, char *readfile) { FILE *rf = NULL; rf = fopen(readfile, "rb"); fseek(rf, 0, SEEK_END); int len = ftell(rf); rewind(rf); char readbuf[len + 1]; int res = fread(readbuf, len, 1, rf); readbuf[le

我从以下函数中得到内存泄漏:

int ReadWrite(int socket, char *readfile) {
  FILE *rf = NULL;
  rf = fopen(readfile, "rb");
  fseek(rf, 0, SEEK_END);
  int len = ftell(rf);
  rewind(rf);

  char readbuf[len + 1];

  int res = fread(readbuf, len, 1, rf);
  readbuf[len + 1] = '\0';
  fclose(rf);
  while (1) {
    int wres = write(socket, readbuf, res);
    if (wres == 0) {
      cerr << "socket closed prematurely" << endl;
      close(socket);
      return EXIT_FAILURE;
    }
    if (res == -1) {
      if (errno == EINTR)
        continue;
      cerr << "socket write failure: " << strerror(errno) << endl;
      close(socket);
      return EXIT_FAILURE;
    }
    break;
  }
  return EXIT_SUCCESS;
}
让我困惑的是,我从来没有在代码中使用new[]。我检查了fopen、ftell和fread,看看他们是否在某处隐藏了他们称之为new[]的“gotcha”,但在cplusplus.com上的文档中没有找到任何东西。我尝试了所有新char[]/delete[]、malloc/free和堆栈分配变量的不同组合(如上所述),但每次都得到相同的valgrind消息。有什么想法吗?谢谢。

你打电话来吗


  • charreadbuf[len+1]

    后来

  • readbuf[len+1]='\0'


这不会使数组溢出吗?

好吧,您正在使用非常量大小(即运行时大小)声明您的
readbuf
数组。这在C++中是非法的。这种特征存在于C99中,而不是C++中。你的代码甚至不会编译成迂腐的C++编译器。您的问题被标记为[C++]

但很有可能编译器将此功能实现为非标准扩展,并通过隐式调用
new[]
创建此类数组。这就是为什么即使未明确使用
new[]
,也会收到指向
new[]
的错误消息

当然,编译器有责任在这些数组的生命周期结束时取消分配它们。我怀疑编译器已经做了它必须做的一切,但是
valgrind
被编译器操作中的某些东西弄糊涂了,这使得它得出结论说这是内存泄漏


此外,正如其他人已经指出的,您正在越界访问您的阵列,这也可能导致运行时出现任何问题,包括来自
valgrind

的奇怪报告。我发现问题实际上与我使用的Makefile有关。不过,谢谢你对我的错误的洞察

charreadbuf[len+1]无效C++。这是一个非常奇怪的代码:'char Read Buff[LeN+1 ]。您使用什么编译器?您可能应该更改
readbuf[len+1]='\0'
readbuf[len]='\0',除非您有意尝试溢出readbuf。此外,你真的使用C99而不是C++吗?更不用说<代码> char Read Buff[LeN+1 ] < /C> >自从代码> LeN<代码>不是代码> const  @ NikBougalis:这仍然是不标准的,但是(a)GCC允许它一段时间,并且(b)他们正在对它进行标准化。GCC手册应该解释如何释放内存(更新:它是由编译器自动释放的),但它不是标准的今天,所以代码不是有效的C++。它是一个有效的“gcc扩展C++”,但这与“C++”不同。是的,它应该自动释放。我不知道错误来自何处我怀疑错误来自一个混乱的
valgrind
,它不理解gcc分配操作的语义。你能解释一下Makefile的问题吗?谢谢。很遗憾,我不记得Makefile引起问题的具体原因。但我记得那是因为我对Makefiles的工作原理有误解。对不起,我没有更多的东西给你-我能做的就是给你指一个关于makefile()的教程。希望这能有所帮助。
Address 0x4c3b67e is 0 bytes after a block of size 14 alloc'd
at 0x4A07C84: operator new[](unsigned long) (vg_replace_malloc.c:363)