无效的realloc / realloc返回NULL

时间:2013-11-16 01:09:47

标签: c structure realloc

在一个函数中,我使用了malloc:

void name1(struct stos* s)
{
   s = malloc (4 * sizeof (int));
}

一切都好。但后来我使用了realloc

void name2(struct stos* s)
{
   s->size = 2*(s->size);
   s = realloc (s, (s->size + 1) * sizeof (int));
}

我在valgrind中得到无效的free / delete / realloc,realloc返回NULL。

结构声明和其余程序是:

struct stos
{
   int top;
   int size;
   int stk[];
};

void name1(struct stos* s);
void name2(struct stos* s);    

int main()
{
   struct stos stosik;
   struct stos* s;
   s = &stosik;

   name1(s);

   //some operations on the array and int top here

   name2(s);
}

我在这里做错了什么?我找了很长时间可能出错的地方,阅读了很多关于指针,malloc / realloc等的文章,但没有结果。如果有人能帮助我,我将非常感激。

2 个答案:

答案 0 :(得分:7)

这个问题有点微妙,是由两件事组合造成的。让我们从这里开始:

struct stos stosik;
struct stos* s;
s = &stosik;

name1(s);

首先,让s指向堆栈上分配的有效内存块(stosik),然后调用name1传入s。让我们来看看name1的样子:

void name1(struct stos* s)
{
    s = malloc (4 * sizeof (int));
}

嗯,我们可以看到name1接收了一个名为struct stos的{​​{1}}的指针;在该函数内部,我们正在分配一些内存并使s指向它。这是一个问题。

首先,请注意s已经指向一个有效的内存块。所以在这里使用s是可疑的。它会导致一个微妙的错误,它实际上会隐藏程序中的真正的错误,这很糟糕。所以,让我们完全删除malloc

stosik

现在,如果您运行此程序,则会在致电int main() { struct stos* s = NULL; name1(s); if(s == NULL) return -1; 后看到变量name1仍然指向s。这里发生了什么?

好吧,我们正在更改NULL的函数的 LOCAL 副本(即仅存在于s内的s)...但是{{在name1中1}}没有改变!请记住,我们正在将指针传递给s,但我们通过值传递

要做你似乎想做的事情你可以做,你必须将指针传递给mainname1(也就是说,传递一个双指针)或者你应该从s返回name1的结果作为返回值。让我们看看每个选项:

通过双指针传递malloc

name1

s调用它需要我们使用“address-of”运算符:

void name1(struct stos **s)
    {
    /* sanity check */
    if(s == NULL)
        return; 

    /* now, allocate enough space for four integers and make 
     * whatever s points to, point to that newly allocated
     * space.
     */
    *s = malloc(4 * sizeof(int));
}

main

返回指向已分配内存的指针
struct stos *s = NULL;

/* we need to pass a pointer to s into name1, so get one. */
name1(&s);

/* malloc can fail; check the result! */
if(s == NULL) 
    return -1;

name1调用此内容稍微容易一些:

struct stos *name1()
{
    return malloc(4 * sizeof(int));
}

将您的代码更改为我在此处显示的内容将解决此问题(但可能还有其他问题),但让我简要介绍其他内容:

另一个错误

由于我们刚刚讨论的问题,您遇到的崩溃部分地突然出现;另一个问题是main内部正在调用struct stos *s = name1(); /* malloc can fail; check the result! */ if(s == NULL) return -1; 。但是,您传递到name2的指针 是您从reallocrealloc返回的指针,这是malloc所期望的。它指向realloc。因此,代码会导致未定义的行为,之后任何都会发生。

如果你很幸运(看起来你似乎),那么它就会崩溃,如果你不是......那么,谁知道会发生什么?

答案 1 :(得分:1)

  1. 如果要在name1中动态分配s,则需要将其声明为name1(struct stos** s),并将指针传递给指向已分配内存的指针。

  2. 您的main分配stosik staticaly,这意味着您无需进行任何进一步的动态分配。然后,当你尝试使用name1(静态分配的mem)时,它确实......嗯,某事。我不知道是什么,但肯定不是你所期待的。