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

发布于 2024-12-08 22:24:59 字数 1963 浏览 0 评论 0原文

我正在尝试使用 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;
}

我所做的是在函数 Growth() 中数组大小加倍后立即打印数组的内容。 编译了代码

我使用: :gcc -version i686-apple-darwin11-llvm-gcc-4.2

及以下是输出:

在此处输入图像描述

中包含意外的 0输出。

请告诉我我在这里做错了什么,谢谢!

I'm trying to implement dynamic array in C using realloc(). My understanding is that realloc() preserves old contents of the memory block the old pointer points to, but my following testing code suggests otherwise:

#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;
}

What I did was print the contents of the array as soon as its size is doubled in function grow(). I compiled the code using:

:gcc -version
i686-apple-darwin11-llvm-gcc-4.2

and below is the output:

enter image description here

with the unexpected 0's in the output.

Please kindly advise what I'm doing wrong here, thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

滥情稳全场 2024-12-15 22:24:59

您在 realloc() 中忘记了 sizeof(int),因此不断缩小数组。

您还需要跟踪动态数组结构中使用的项数和分配的空间量;这是两项单独的措施,而且都是必要的。但是您不能使用全局变量(当前为 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;
}

You forgot sizeof(int) in your realloc(), so you keep shrinking your array.

You also need to keep track of the number of items in use and the amount of space allocated in the dynamic array structure; these are two separate measures, and both are needed. But you can't use a global variable (currently DYNARRAYSIZE) to hold the size of every dynamic array. You need one per dynamic array.

You also need to look at full(); it compares the size with DARRAYSIZE...always!


Working Output

Formatted with tabstops set at 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

Working Code

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文