我目前正在学习 C 并且必须编写“动态数组”。
在提供给我们的头文件中,struct DynArray 声明为
struct DynamicArray
{
unsigned int size;
unsigned int capacity;
int *data;
};
我已经实现了dyn_array程序中的大部分功能,提供的是空函数。
我的困难在于函数 dn_append(DynamicArray *a, int elem)。我得到的唯一描述是
// =====================================================================================
// Name: dn_append
// Description: Append an element.
//
// Parameters: a - the array
// elem - the new value
// Returns: non-zero, if the array was successfully extended
// =====================================================================================
我们有一个 makefile 来编译这个和一些测试用例。在其中一个测试程序中,初始化了一个新的 DynArray,然后附加了一些值:
int
main ( int argc, char *argv[] )
{
DynamicArray *a1;
int i;
a1 = dn_new ( 5 );
dn_append ( a1, 5 );
dn_append ( a1, 7 );
dn_append ( a1, 8 );
dn_append ( a1, 11 );
dn_append ( a1, 13 );
dn_append ( a1, 15 );
dn_set ( a1, 2, 9 );
for ( i = 0; i < dn_size ( a1 ); i += 1 )
{
printf ( "%d\n", dn_get ( a1, i ) );
}
dn_destory ( a1 );
return 0;
}
它因段错误而中止。
我的(错误的)实现如下。外部 else-case 完全搞砸了,因为调试让我发疯。 (请注意,我在代码示例之后解释了有问题的行。)
int
dn_append ( DynamicArray *a, int elem )
{
printf("\n\nAppend:\n");
if (a->size >= a->capacity) {
printf("Array too small");
int *dataPtr = realloc(a->data, 2*a->capacity);
if (dataPtr != NULL) {
a->capacity *= 2;
a->data = dataPtr;
a->data[a->size] = elem;
a->size++;
}
else {
return 0;
}
}
else {
int *dataPtr;
dataPtr = a->data;
printf("Size: %d, Capacity: %d\n", a->size, a->capacity);
int sizeN = a->size;
printf("Size: %d, Capacity: %d\n", a->size, a->capacity);
//int offset = sizeN;
int *temp;
temp = dataPtr;// + offset;
//dataPtr[offset] = elem;
//printf("Data at %d is %d, should be %d\n", offset, *(a->data), elem);
a->size++;
}
return 1;
}
有问题的行在外面的 else-case 中,在中间:
printf("Size: %d, Capacity: %d\n", a->size, a->capacity);
int sizeN = a->size;
printf("Size: %d, Capacity: %d\n", a->size, a->capacity);
当我运行程序时,这些行打印出来
Size: 0, Capacity: 5
Size: 0, Capacity: 0
我什至没有触及该结构的 capacity
组件,但它将其设置为 0,这完全搞砸了以下程序。
注释完 int sizeN = a->size;
行后,capacity
就应该是左右了。
我需要以某种方式读取 size
。
那么,到底为什么要更改该组件?
一些附加信息:
DynamicArray*
dn_new ( unsigned int capacity )
{
if (capacity > 0) {
int *dataPtr = malloc(capacity*sizeof(int));
if (dataPtr != NULL) {
struct DynamicArray array = { 0, capacity, dataPtr };
return &array;
}
else {
return NULL;
}
}
else {
return NULL;
}
}
最佳答案
在你的 dn_new()
中你有:
if (dataPtr != NULL) {
struct DynamicArray array = { 0, capacity, dataPtr };
return &array;
}
这里,array
是一个局部变量;返回后将超出范围。您应该为此在堆上分配内存:
struct DynamicArray *array = malloc(sizeof *array);
array->size = 0;
array->capacity = capacity;
array->data = dataPtr;
return array;
并记住在析构函数 (dn_destroy()
) 中free()
这段内存。
关于复制结构的组件会删除同一结构的另一个组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30002736/