【问题标题】:Memory allocation problem C/Cpp Windows critical error内存分配问题 C/Cpp Windows 严重错误
【发布时间】:2011-01-30 00:42:39
【问题描述】:

我有一段代码需要从 C 语言“翻译”为 Cpp,但我无法理解,哪里出了问题。有一部分,它崩溃了(Windows严重错误发送/不发送):

 nDim = sizeMax*(sizeMax+1)/2;
 printf("nDim  = %d sizeMax = %d\n",nDim,sizeMax);
 hamilt = (double*)malloc(nDim*sizeof(double));
 printf("End hamilt alloc. %d allocated\n",(nDim*sizeof(double)));
 transProb = (double*)malloc(sizeMax*sizeMax*sizeof(double));
 printf("End transProb alloc. %d allocated\n",(sizeMax*sizeMax*sizeof(double)));
 eValues = (double*)malloc(sizeMax*sizeof(double));
 printf("eValues allocated. %d allocated\n",(sizeMax*sizeof(double)));
    eVectors  = (double**)malloc(sizeMax*sizeof(double*));
 printf("eVectors allocated. %d allocated\n",(sizeMax*sizeof(double*)));
 if(eVectors) for(i=0;i<sizeMax;i++) {
                 eVectors[i] = (double*)malloc(sizeMax*sizeof(double));
                 printf("eVectors %d-th element allocated. %d allocated\n",i,(sizeMax*sizeof(double)));
                 }
 eValuesPrev = (double*)malloc(sizeMax*sizeof(double));
 printf("eValuesPrev allocated. %d allocated\n",(sizeMax*sizeof(double)));
 eVectorsPrev  = (double**)malloc(sizeMax*sizeof(double*));
 printf("eVectorsPrev allocated. %d allocated\n",(sizeMax*sizeof(double*)));
 if(eVectorsPrev) for(i=0;i<sizeMax;i++) {
                     eVectorsPrev[i] = (double*)malloc(sizeMax*sizeof(double));
                     printf("eVectorsPrev %d-th element allocated. %d allocated\n",i,(sizeMax*sizeof(double)));
                     }

日志:

nDim  = 2485 sizeMax = 70
End hamilt alloc. 19880 allocated
End transProb alloc. 39200 allocated
eValues allocated. 560 allocated
eVectors allocated. 280 allocated 

所以它在分配循环开始时崩溃。如果我删除这个循环,它会在下一行分配时崩溃。这是否意味着像这样的数字我没有足够的内存?

谢谢。

【问题讨论】:

  • 啊.. 请更好的格式!

标签: c++ windows memory allocation


【解决方案1】:

您可能没有尝试分配太多内存。其他一些代码可能有corrupted the heap,之后它可以咬住代码中的任意一点。请参阅链接以获取调试帮助。

如果您在无缺陷程序中内存不足,malloc 将返回错误指示。

【讨论】:

    【解决方案2】:

    在我的机器上,这个程序在通过 valgrind 运行时编译、执行没有错误并且没有报告内存问题。除非您在小型嵌入式系统上运行,否则您的问题很可能出在此代码之外,因为此程序分配的内存总量不到 140 KiB。

    此外,当malloc 失败时,它不会崩溃,它会返回 NULL。此代码正确检查 eVectorsPrev 是否为 NULL,因此此处不应存在 NULL 取消引用问题。

    【讨论】:

    • >> 小于 140 KiB。确切地。实际上,在此之前有一些错位,但大小或多或少相同。请告诉我,是否有可能查看我是否内存不足?或者我怎样才能“抓住”崩溃的原因?还有一个:我刚刚注意到 C 版本通常是由我的 DevC++ 的同一个编译器编译的,尽管有像 hamilt = malloc(nDim*sizeof(double)); 这样的行。没有精确的类型。正常吗?或者我遇到了一些奇怪的编译器设置?
    • hamilt 等变量的类型必须声明为 somewhere 否则无法编译。它们可能是函数的参数或全局变量。要检测内存损坏问题(这很可能是这种情况)和/或读取正在使用的内存量,请使用内存分析器/调试器。我使用 valgrind,但那是在 Linux 上。这篇文章对类似 valgrind 的 windows 工具有一些很好的建议:stackoverflow.com/questions/413477/…
    • 是的,类型是之前声明的。但对我来说似乎很奇怪的是,在精确每个 malloc 的类型之前,我无法编译新版本(也在 C 上给我)。但前一个编译。哪里有区别?
    • 哦,你说的是(double*) 等在malloc 通话中的演员表。在 C 中,这可以省略,因为 malloc 返回 void* 隐式转换为任何指针类型。 C++ 作为一种不同的语言,需要您进行显式转换。但是在 C++ 中,您确实应该使用 new[] 而不是 malloc,或者如果您要使用 malloc,至少使用 static_cast 而不是您发布的 C 样式转换。
    • @andrew:堆损坏发生在有时与指示损坏的代码相距很远的地方;添加新代码可能会暴露一些完全不相关的代码中发生的堆损坏。
    【解决方案3】:

    sizeMax 是什么?我没有看到声明,请修复格式。附注...您在不检查它是否有效的情况下盲目地调用malloc...这是一个危险的假设-永远不要假设有足够的内存可用,因为堆可能变得非常碎片化并且当调用@ 987654323@ 对于碎片堆中的一个非常小的对象可能会失败,因为没有足够的内存...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-14
      • 2021-05-04
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      • 2014-06-21
      相关资源
      最近更新 更多