无效的realloc/realloc返回NULL

Vla*_*mir 2 c structure realloc

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

void name1(struct stos* s)
{
   s = malloc (4 * sizeof (int));
}
Run Code Online (Sandbox Code Playgroud)

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

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

我在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);
}
Run Code Online (Sandbox Code Playgroud)

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

Nik*_*lis 7

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

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

name1(s);
Run Code Online (Sandbox Code Playgroud)

首先,s指出在堆栈(stosik)上分配的有效内存块,然后调用name1传入s.让我们来看看是什么name1样的:

void name1(struct stos* s)
{
    s = malloc (4 * sizeof (int));
}
Run Code Online (Sandbox Code Playgroud)

嗯,我们可以看到name1接收到一个struct stos被调用的指针s; 在该函数内部,我们正在分配一些内存并s指出它.这是个问题.

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

int main()
    {
    struct stos* s = NULL;

    name1(s);

    if(s == NULL)
        return -1;
Run Code Online (Sandbox Code Playgroud)

现在,如果你运行这个程序,你会看到在调用name1变量后s仍然指向NULL.这里发生了什么事?

好吧,我们正在更改函数的LOCAL副本s(即s仅存在于内部name1)......但是sin main不会改变!请记住,我们正在将指针传入,name1但我们正在按值传递它.

要做到你仿佛是试图做,你可以做你就必须要么通过一个指针s进入name1(即,通过双指针),或者你应该返回的结果mallocname1作为返回值.让我们看看每个选项:

通过s经由双指针在

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));
}
Run Code Online (Sandbox Code Playgroud)

调用它main需要我们使用"address-of"运算符:

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;
Run Code Online (Sandbox Code Playgroud)

从中返回指向已分配内存的指针 name1

struct stos *name1()
{
    return malloc(4 * sizeof(int));
}
Run Code Online (Sandbox Code Playgroud)

从中调用此main更容易:

struct stos *s = name1();

/* malloc can fail; check the result! */
if(s == NULL)
    return -1;
Run Code Online (Sandbox Code Playgroud)

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

另一个错误

你遇到的崩溃部分是因为我们刚刚解决的问题; 另一个问题是,name2你正在打电话realloc.您传递到指针realloc但是,是不是,你有从后一个指针malloc或者realloc,这就是realloc希望.它指向了stosik.因此代码会导致未定义的行为,之后就会发生任何事情.

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