首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Realloc论点

Realloc论点
EN

Stack Overflow用户
提问于 2015-08-19 12:18:03
回答 3查看 1.2K关注 0票数 2

我使用下面的代码使用数组实现堆栈

代码语言:javascript
复制
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct Stack{
int top;
int capacity;
int *array;
};

struct Stack *createStack()
{
        struct Stack *stack=malloc(sizeof(struct Stack));
        stack->top=-1;
        stack->capacity=1;
        stack->array=malloc(sizeof(sizeof(int)*stack->capacity));
}
void doubleStack(struct Stack *stack)
{
        stack->capacity=stack->capacity*2;
        stack->array=realloc(stack,stack->capacity);
}
void push( struct Stack *stack , int data)
{
        if(stack->top==(stack->capacity)-1)
                doubleStack(stack);
        stack->array[++stack->top]=data;
}

我的疑问是,一旦堆栈满了,当调用doubleStack时,是使用stack->array作为realloc()的第一个参数还是使用stack作为realloc()的第一个参数?

我认为stack->array应该通过。因为我们只需要重新分配内存的那一部分。

但我意外地通过了stack,这似乎也奏效了。请给我建议。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-08-19 12:21:09

您应该向realloc传递一个指向希望扩展的数组的指针。由于stack不是您希望扩展的数组,而stack->array是数组,所以您应该将stack->array作为第一个参数传递。

但是,您应该将realloc的结果存储在一个单独的变量中,并执行NULL检查。

如果函数未能分配请求的内存块,则返回一个空指针,并且参数ptr所指向的内存块不会被释放(它仍然有效,且其内容不变)。

否则,您可能会产生内存泄漏:

代码语言:javascript
复制
int *tmp = realloc(stack->array, stack->capacity);
if (tmp) {
    stack->array = tmp;
} else {
    ... // Deal with the allocation error here
}
票数 2
EN

Stack Overflow用户

发布于 2015-08-19 12:20:35

正如你正确的想法,

代码语言:javascript
复制
  stack->array=realloc(stack,stack->capacity);

至少应该是

代码语言:javascript
复制
  stack->array=realloc(stack->array,stack->capacity);

否则,如果成功,您将是free()-ing up stack本身,然后您将访问它。调用未定义行为。一旦你有了UB,很多东西就“看起来”起作用了。

也就是说,从使用的角度来看,

代码语言:javascript
复制
 p = realloc(p, q); 

代码类型非常糟糕,好像realloc()失败了一样,它不会修改作为参数传递的p,但是由于直接将realloc()的返回值赋值给pp将被设置为NULL,从而丢失了实际存储的指针。

提示:始终使用临时指针收集realloc()的返回值,然后检查realloc()成功与否,如果realloc()成功,则将新返回的指针分配给传递给realloc()的指针。

票数 2
EN

Stack Overflow用户

发布于 2015-08-19 12:37:38

首先,函数push是错误的

代码语言:javascript
复制
void push( struct Stack *stack , int data)
{
        if(stack->top==(stack->capacity)-1)
                doubleStack(stack);
        stack->array[++stack->top]=data;
}

最初,top设置为1,capacity也设置为1。

所以这个条件

代码语言:javascript
复制
if(stack->top==(stack->capacity)-1)

生成false和下面的语句

代码语言:javascript
复制
stack->array[++stack->top]=data;

被处决了。它将写入超出分配数组的内存stack->array[2]

我认为最初top应该设置为0。该函数的定义方式如下

代码语言:javascript
复制
void push( struct Stack *stack , int data )
{
        if ( stack->top != stack->capacity || doubleStack( stack ) )
        {
            stack->array[stack->top++] = data;
        } 
}

在这种情况下,您可以简单地定义一个函数,该函数以下列方式报告堆栈是否为空

代码语言:javascript
复制
int empty( struct Stack *stack ) { return stack->top == 0; }

至于函数doubleStack,则应按以下方式定义

代码语言:javascript
复制
int doubleStack(struct Stack *stack)
{
        int success = 0;

        int new_capacity = 2 * stack->capacity;

        int *tmp = = realloc( stack->array, new_capacity * sizeof( int ) );

        if ( ( success = tmp != NULL ) ) 
        {
            stack->capacity = new_capacity;
            stack->array = tmp;
        }

        return success
}

考虑到我将函数的返回类型从void更改为int。此外,我还使用了一个中间变体new_capacity。如果重新分配失败,则不会更改当前容量。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32095311

复制
相关文章

相似问题

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