Использование realloc () в реализации динамического массива - PullRequest
0 голосов
/ 06 октября 2011

Я пытаюсь реализовать динамический массив в C, используя realloc ().Насколько я понимаю, 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-apple-darwin11-llvm-gcc-4.2

и ниже вывод:

enter image description here

с неожиданными 0 на выходе.

Пожалуйста, сообщите мне, что я делаю не так, спасибо!

1 Ответ

3 голосов
/ 06 октября 2011

Вы забыли 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...