我正在尝试使用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
以下是输出:
输出中出现意外的0。
请在这里告知我的错误,谢谢!
答案 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;
}