重新分配时出现段错误

发布于 2024-12-08 09:22:40 字数 939 浏览 1 评论 0原文

所以我在程序中使用 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);
 }

 }

So I was using malloc in my program and then realloc within a method inside the program. After I called this method so many times I would get a "Segmentation fault (core dumped)".

Upon further inspection I realized that for some reason when my pointer goes from 0x25d7d60 or 0x223fae0 (or any address represented by 7 digits (0xHHHHHHH) ) to 0x7f47d370a010 (with more than 7 digits) for example, a segfault is thrown from within the realloc call, realloc wont even return NULL. I fixed this by simply using malloc and then memcpy instead. However I am very confused at why this happened and wanted to see if any of the users of stackoverflow could shed some light on why this happened.

Thanks

Here is the relevant code:

 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);
 }

 }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

没有心的人 2024-12-15 09:22:40

有一个很好的机会,通过调用“程序内方法内的 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;
}

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

因此,问题超出了您向我们展示的范围,可能是编译器错误(如果您使用主流编译器,则不太可能)或代码中其他地方的内存损坏。

There's a good chance that, by calling "realloc within a method inside the program", you're actually loading it into a local variable which is then thrown away and your program continues to use the older pointer (which has now been freed).

We would need to see the code to be certain but, in my experience, that's the one of the major causes of allocation errors.


Based on what you've shown, there's nothing wrong with what you're doing. It's effectively the same as this code:

#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;
}

which works perfectly, doing ten million reallocations.

So the problems lies outside what you've shown us, perhaps a compiler bug (pretty unlikely if you're using a mainstream compiler) or memory corruption from elsewhere in your code.

樱&纷飞 2024-12-15 09:22:40

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

+---------+
| 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)

If realloc changes the address of the array, then the myarr in the function scope (local) gets the new value, it does not change the myarr variable in the main

+---------+
| 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)
感情旳空白 2024-12-15 09:22:40

您没有在主作用域中更改 myArr,realloc 可能会返回新地址,旧地址无效。

You didn't change myArr in the main scope, realloc maybe return a new address, the old address is invalid.

神魇的王 2024-12-15 09:22:40

问题是您的 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()< 的内存地址/code>s myArr 以便可以写入其中。

正如您所看到的,使用输出值的函数参数可能会有点麻烦,因此我建议返回新地址:

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

然后只需覆盖 myArr 主要

myArr = methodName(myArr, n_ints);

The problem is that your methodName function is assigning the new pointer to it's local copy of myArray.

The quick fix is to make myArray a pointer to a pointer like so:

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);
    }
}

and then call it by passing the address of myArr:

methodName(&myArr, n_ints);

That way methodName gets the address of the memory of main()s myArr so that it can write into it.

As you can see though, having function parameters that output values can get a little hairy so I suggest instead returning the new address:

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

Then it's just a matter of overwriting myArr in main:

myArr = methodName(myArr, n_ints);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文