首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无效的realloc/realloc返回空

无效的realloc/realloc返回空
EN

Stack Overflow用户
提问于 2013-11-16 01:09:46
回答 2查看 2.9K关注 0票数 2

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

代码语言:javascript
复制
void name1(struct stos* s)
{
   s = malloc (4 * sizeof (int));
}

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

代码语言:javascript
复制
void name2(struct stos* s)
{
   s->size = 2*(s->size);
   s = realloc (s, (s->size + 1) * sizeof (int));
}

在val差内,我得到了无效的空闲/删除/ realloc,然后realloc返回NULL。

程序的结构和其余部分的声明如下:

代码语言:javascript
复制
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等的文章,但没有结果。如果有人能帮我,我会很感激的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-16 01:12:03

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

代码语言:javascript
复制
struct stos stosik;
struct stos* s;
s = &stosik;

name1(s);

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

代码语言:javascript
复制
void name1(struct stos* s)
{
    s = malloc (4 * sizeof (int));
}

嗯,我们可以看到name1接受一个指向名为sstruct stos的指针;在这个函数中,我们分配一些内存并让s指向它。这是一个问题。

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

代码语言:javascript
复制
int main()
    {
    struct stos* s = NULL;

    name1(s);

    if(s == NULL)
        return -1;

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

我们正在更改s的本地副本(即仅存在于name1中的s ).但是s in main并没有改变!请记住,我们将一个指针传递到name1,但我们是通过值传递它。

要完成您想要做的事情,您必须将指向s的指针传递到name1 (即传递一个双指针),或者将malloc的结果从name1返回为一个返回值。让我们看看这些选项中的每一个:

通过双指针传入s

代码语言:javascript
复制
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调用它需要我们使用"address-of“操作符:

代码语言:javascript
复制
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返回一个指向分配内存的指针

代码语言:javascript
复制
struct stos *name1()
{
    return malloc(4 * sizeof(int));
}

main调用它稍微容易一些:

代码语言:javascript
复制
struct stos *s = name1();

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

将您的代码更改为我在这里向您展示的代码将解决这个问题(但可能还有其他问题),但让我简单地谈谈其他一些内容:

另一个臭虫

您遇到的崩溃部分是因为我们刚才讨论的问题;另一个问题是在name2中调用realloc。但是,传入realloc的指针是而不是,这是从mallocrealloc获得的指针,这正是realloc所期望的。相反,它指向stosik。因此,代码会导致未定义的行为,在此之后,任何事情都可能发生。

如果你很幸运(看起来你是),它就会突然坠毁,如果你不是.谁知道会发生什么呢?

票数 9
EN

Stack Overflow用户

发布于 2013-11-16 03:36:05

  1. 如果要在name1中动态分配s,则需要将其声明为name1(struct stos** s),并将指针传递到应该显示分配内存的指针。
  2. 您的main分配stosik staticaly,这意味着您不需要做任何进一步的动态分配。然后,当您尝试执行name1(静态分配mem)时,它会执行…呃,什么的。我不知道是什么,但肯定不是你期望的那样。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20013368

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档