在动态数组实现中使用realloc()

时间:2011-10-06 02:23:10

标签: c memory-management

我正在尝试使用realloc()在C中实现动态数组。我的理解是realloc()保留旧指针指向的内存块的旧内容,但我的下面的测试代码暗示:

#include <stdio.h>
#include <stdlib.h>

int DARRAYSIZE=5;

typedef struct dynamicArray{
    int size;
    int *items;
}DArray;

int init(DArray *DAP){ //initialise the DArray
    DAP->items=(int *)malloc(sizeof(int)*DARRAYSIZE);
    if(DAP->items){
        DAP->size=0;
        return 0;
    }else{
        printf("Malloc failed!\n");
        return 1;
    }
}

void print(DArray *DAP){ //print all elements in the DArray
    int i=0;

    for(;i<DAP->size;i++)
        printf("%d\t",DAP->items[i]);

    printf("\n");
}

void add(DArray *DAP,int val){ //add the new val into the DArray
    if(!full(DAP)){
        DAP->items[DAP->size++]=val;    
    }else{
        if(!grow(DAP)){
            DAP->items[DAP->size++]=val;    
        }else
            exit(1);
    }
}

int full(DArray *DAP){ //returns 1 if the DAarray is full
    if(DAP->size==DARRAYSIZE)
        return 1;
    else
        return 0;
}

int grow(DArray *DAP){ //grows the DArray to double its original size
    int *temp=(int *)realloc(DAP->items,DARRAYSIZE*2);
    if(!temp){
        printf("Realloc failed!\n");
        return 1;
    }else{
        DAP->items=temp;
        DARRAYSIZE*=2;
        printf("Darray doubled and current contents are:\n");
        print(DAP);
        return 0;
    }
}

void destroy(DArray *DAP){ //destroies the DArray
    free(DAP->items);
}

int main(void){
    DArray newDA;
    if(!init(&newDA)){
        int i;
        for(i=1;i<30;i++)
            add(&newDA,i);

    }else
        exit(1);

    destroy(&newDA);

    return 0;
}

我所做的是在函数grow()中将其大小加倍后立即打印数组的内容。我用以下代码编译了代码:

:gcc -version i686的-苹果darwin11-LLVM-GCC-4.2

以下是输出:

enter image description here

输出中出现意外的0。

请在这里告知我的错误,谢谢!

1 个答案:

答案 0 :(得分:3)

您忘记了sizeof(int)中的realloc(),因此您的阵列不断缩小。

您还需要跟踪正在使用的项目数和动态数组结构中分配的空间量;这是两个独立的措施,都需要。但是您不能使用全局变量(当前为DYNARRAYSIZE)来保存每个动态数组的大小。每个动态数组需要一个。

您还需要查看full();它将尺寸与DARRAYSIZE进行比较......总是!


工作输出

使用设置为3

的制表符进行格式化
Darray doubled and current contents are:
Max = 10; Cur = 5
1  2  3  4  5
Darray doubled and current contents are:
Max = 20; Cur = 10
1  2  3  4  5  6  7  8  9  10
Darray doubled and current contents are:
Max = 40; Cur = 20
1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20

工作代码

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

enum { DARRAYSIZE = 5 };

typedef struct dynamicArray
{
    int max_size;
    int cur_size;
    int *items;
} DArray;

extern int  init(DArray *DAP);
extern void add(DArray *DAP, int val);
extern void destroy(DArray *DAP);
extern void print(DArray *DAP);
static int  full(DArray *DAP);
static int  grow(DArray *DAP);

//initialise the DArray
int init(DArray *DAP)
{
    DAP->items=(int *)malloc(sizeof(int)*DARRAYSIZE);
    if (DAP->items)
    {
        DAP->max_size = DARRAYSIZE;
        DAP->cur_size = 0;
        return 0;
    }
    else
    {
        printf("Malloc failed!\n");
        return 1;
    }
}

//print all elements in the DArray
void print(DArray *DAP)
{
    printf("Max = %d; Cur = %d\n", DAP->max_size, DAP->cur_size);
    for (int i = 0; i < DAP->cur_size; i++)
        printf("%d\t", DAP->items[i]);
    printf("\n");
}

//add the new val into the DArray
void add(DArray *DAP, int val)
{
    if (!full(DAP))
        DAP->items[DAP->cur_size++] = val;    
    else if (!grow(DAP))
        DAP->items[DAP->cur_size++] = val;    
    else
        exit(1);
}

//returns 1 if the DAarray is full
static int full(DArray *DAP)
{
    assert(DAP->cur_size >= 0 && DAP->max_size >= 0);
    assert(DAP->cur_size <= DAP->max_size);
    if (DAP->cur_size == DAP->max_size)
        return 1;
    else
        return 0;
}

//grows the DArray to double its original size
static int grow(DArray *DAP)
{
    int *temp=(int *)realloc(DAP->items, sizeof(*temp) * DAP->max_size * 2);
    if (!temp)
    {
        printf("Realloc failed!\n");
        return 1;
    }
    else
    {
        DAP->items = temp;
        DAP->max_size *= 2;
        printf("Darray doubled and current contents are:\n");
        print(DAP);
        return 0;
    }
}

//destroys the DArray
void destroy(DArray *DAP)
{
    free(DAP->items);
    DAP->items = 0;
    DAP->max_size = 0;
    DAP->cur_size = 0;
}

int main(void)
{
    DArray newDA;
    if (!init(&newDA))
    {
        for (int i = 1; i < 30; i++)
            add(&newDA, i);
    }
    else
        exit(1);

    destroy(&newDA);

    return 0;
}