我目前正在学习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-分支完全混乱了,因为调试让我抓狂。(请注意,在代码示例后面我会解释有问题的那一行。)
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语句中间:
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;
}
}
valgrind
和/或调试器中运行您的代码。 - Matvalgrind
告诉我,对于每一行我使用printf()
,都会出现Conditional jump or move depends on uninitialised value(s)
和Use of uninitialised value of size 8
的错误。此外,我也不知道什么是分配器函数。 - J0hj0hdn_new()
。 - user12205