【问题标题】:Segfault with realloc带 realloc 的段错误
【发布时间】:2011-10-05 04:47:11
【问题描述】:

所以我在我的程序中使用 malloc,然后在程序内部的方法中重新分配。在我多次调用此方法后,我会收到“分段错误(核心转储)”。

经过进一步检查,我意识到由于某种原因,例如,当我的指针从 0x25d7d60 或 0x223fae0(或由 7 位 (0xHHHHHHH) 表示的任何地址)变为 0x7f47d370a010(超过 7 位)时,会从内部引发段错误realloc 调用,realloc 甚至不会返回 NULL。我通过简单地使用 malloc 然后 memcpy 解决了这个问题。但是,我对为什么会发生这种情况感到非常困惑,并想看看是否有任何 stackoverflow 用户可以解释为什么会发生这种情况。

谢谢

以下是相关代码:

 unsigned int* myArray;
 unsigned int num_ints;

 int main()
 {

   num_ints = 100; 
   if((myArray =(unsigned int*) malloc(sizeof(unsigned int)*(num_ints)*3))==NULL)
   {
    std::cout << "Malloc failed!" << std::endl;
    return false;
   }

   .
   .
   .

   //This called when n key is pressed (code left out)
   methodName();
 return true;
 }

 void methodName()
 {

 if((myArray =(unsigned int*) realloc(myArray,sizeof(unsigned int)*(num_ints*4)*3))==NULL)
 {
    std::cout << "Realloc failed!" << std::endl;
    exit(0);
 }

 }

【问题讨论】:

  • 应该是C还是C++???为什么它被标记为 C 却使用 std::cout
  • 它是 C++,我只是标记了 C,因为 realloc 在 C 中使用,我根本不使用 C++ 函数,但需要使用 g++ 编译。
  • @Matt:不要在 C++ 中使用 malloc、realloc 或 free。
  • 投票结束,因为问题不在发布的代码中。

标签: c++ malloc realloc


【解决方案1】:

很有可能,通过调用“程序内部方法中的 realloc”,您实际上是将其加载到一个局部变量中,然后该变量被丢弃,您的程序继续使用旧指针(现在已释放)。

我们需要查看代码才能确定,但​​根据我的经验,这是分配错误的主要原因之一。


根据您所展示的内容,您的操作没有任何问题。它实际上与此代码相同:

#include <iostream>
#include <cstdlib>
int sz = 1000;
int *buffer = 0;
static int methodName (void) {
    if (sz == 100000)
        sz = 100;
    sz = sz * 10;
    if ((buffer = (int*)realloc (buffer, sz)) == 0) {
        std::cout << "Realloc error" << std::endl;
        return 1;
    }
    return 0;
}
int main(void) {
    int i;
    if ((buffer = (int*)malloc (sz)) == 0) {
        std::cout << "Alloc error" << std::endl;
        return 1;
    }
    for (i = 0; i < 10000000; i++)
        if (methodName() != 0)
            return 1;
    std::cout << "All okay" << std::endl;
    return 0;
}

完美运行,进行一千万次重新分配。

所以问题不在于您向我们展示的内容,可能是编译器错误(如果您使用的是主流编译器,则几乎不可能)或代码中其他地方的内存损坏。

【讨论】:

  • 我在帖子中添加了代码。它不是我使用的实际代码,但非常相似。我使用的代码将指针作为全局变量。
  • @Matt,我看不出你发布的代码有什么问题。您应该发布真实代码或至少发布出现问题的代码(最好是最小的变体)。
  • 我同意。这是我的实际代码,除了我更改了 myArray 和 num_ints 变量名称以及 methodName 的名称。
  • @Matt:那么除了您向我们展示的内容之外,您的编译器或代码有问题。我已经运行了几乎完全相同的代码,在数百万次迭代中将内存重新分配到 1K 到 100K 之间的随机值,并且运行良好。
【解决方案2】:

如果realloc改变了数组的地址,那么函数作用域(本地)中的myarr得到了新的值,它不会改变main中的myarr变量

+---------+
| val1    |  = malloc (whatever);    <--------------------------+
+---------+                                                     |
|myarr    |                                                     |
+---------+                                                     |
|addr_main|                                                     |
+----+----+                                                     |
     |                                                          |
     |                                                          |
     |                                                (NO EFFECT on here)
(value of the myaddr 'val1')                                    |
(in main passed by value)                                       |
(to function)                                                   |
     |                                                          |
     +-------+                                                  |
             |                                                  |
             v                                                  |
methodname (myarr, someint)                                     |
             |                                                  |
             |                                                  |
             V                                                  |
        +---------+                                             |
        |  val1   |    = realloc (myarr, whatever)     ---------+
        +---------+    
        |myarr    |    if 'realloc' returns a new address
        +---------+    it will only overwrite 'val1' with some 'val2' 
        |addr_func|    in this LOCAL copy with address 'addr_func' 
        +---------+
             |
             |
             V
     (destroyed after function return)

【讨论】:

  • 好的,这不是我的实际代码...我只是在运行中完成的。我的实际代码在我的学校计算机上,而不是这个。在我的实际代码中 myArray 是一个全局变量
  • 我知道它应该并且它可以工作,直到我按下 n 键以获得更多内存,比如十次,并且当前内存的地址是 0xHHHHHHH 并且在它失败之前第一次是 0xHHHHHHHHHHHH。它在我的 Mac 上运行良好,当我 ssh 进入 Linux 机器时,但当我在 Linux 机器上时却不行。
【解决方案3】:

你没有在主范围内更改 myArr,realloc 可能返回一个新地址,旧地址无效。

【讨论】:

  • 好的,这不是我的实际代码...我只是在运行中完成的。我的实际代码在我的学校计算机上,而不是这个。在我的实际代码中,myArray 是一个全局变量
【解决方案4】:

问题是您的 methodName 函数将新指针分配给它的本地 myArray 副本。

快速解决方法是让 myArray 成为指向如下指针的指针:

void methodName(unsigned int **myArray, unsigned int num_ints)
{
    if((*myArray = (unsigned int *)realloc((*myArray), sizeof(unsigned int)*(num_ints*4)*3)) == NULL)
    {
        std::cout << "Realloc failed!" << std::endl;
        exit(0);
    }
}

然后通过传递myArr的地址来调用它:

methodName(&myArr, n_ints);

这样methodName就可以得到main()s myArr的内存地址,这样就可以写入了。

正如你所看到的,具有输出值的函数参数可能会有点麻烦,所以我建议改为returning 新地址:

unsigned int *methodName(unsigned int *myArray, unsigned int num_ints)
{
    return (unsigned int *)realloc(myArray, sizeof(unsigned int) * (num_ints * 4) *3); 
}

那么这只是在main中覆盖myArr的问题:

myArr = methodName(myArr, n_ints);

【讨论】:

  • 好的,这不是我的实际代码...我只是在运行中完成的。我的实际代码在我的学校计算机上,而不是这个。在我的实际代码中 myArray 是一个全局变量
  • @Matt 在此处发布问题时,这些细节非常重要。如果您修复问题中的代码,我将更新此答案。
  • 我认为更新后的代码没有任何问题。问题可能不在重新分配中。也许其他人可以发现它。
  • 我也没有发现任何问题。这就是我问这个问题的原因。它一直有效,直到我按下 n 键以获得更多内存(如 10 次)并且当前内存的地址为 0xHHHHHHH 并且在它失败之前第一次为 0xHHHHHHHHHHHH 。它在我的 Mac 上运行良好,当我 ssh 进入 Linux 机器时,但当我在 Linux 机器上时却不行。
猜你喜欢
  • 2014-06-05
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多