I am currently learning C and have to program a "dynamic array".
我目前正在学习C并且必须编写一个“动态数组”。
In a header file provided to us, the struct DynArray is declared as
在提供给我们的头文件中,结构DynArray声明为
struct DynamicArray
{
unsigned int size;
unsigned int capacity;
int *data;
};
I have already implemented most of the functions in the dyn_array program, which was provided with empty functions.
My difficutly lies with the function dn_append(DynamicArray *a, int elem). The only description I have been given is
我已经在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
// =====================================================================================
We have a makefile to compile this and a few test cases. In one of the test programs, a new DynArray is initialized and then a few values are appended:
我们有一个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;
}
It aborts with a segmentation fault.
My (faulty) implementation is as follows. The outer else-case is completely messed up, since the debugging drove me crazy. (Note that I explain the problematic line after the code sample.)
它会因分段错误而中止。我的(错误的)实现如下。外部的其他情况完全搞砸了,因为调试让我抓狂。 (请注意,我在代码示例后解释了有问题的行。)
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;
}
The problematic line is in the outer else-case, in the middle:
有问题的行在外部的其他情况下,在中间:
printf("Size: %d, Capacity: %d\n", a->size, a->capacity);
int sizeN = a->size;
printf("Size: %d, Capacity: %d\n", a->size, a->capacity);
When I run the program, these lines print out
当我运行程序时,这些行打印出来
Size: 0, Capacity: 5
Size: 0, Capacity: 0
I don't even touch the capacity
-component of the struct, but it sets it to 0, which completely f***s up the following program.
我甚至没有触摸结构的容量组件,但它将其设置为0,这完全可以解决以下程序。
After commenting the line int sizeN = a->size;
, the capacity
is left right as it should.
I need to read the size
, one way or another.
在注释int sizeN = a-> size;之后,容量保持正确。我需要以这种或那种方式阅读尺寸。
So, why the hell does it change that component?
那么,为什么它会改变那个组件呢?
Some additional infos:
一些额外的信息:
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;
}
}
2 个解决方案
#1
In your dn_new()
you have:
在你的dn_new()中你有:
if (dataPtr != NULL) {
struct DynamicArray array = { 0, capacity, dataPtr };
return &array;
}
Here, array
is a local variable; it will be out of scope after returning it. You should allocate memory on the heap for that:
这里,array是一个局部变量;返回后它将超出范围。您应该为堆分配内存:
struct DynamicArray *array = malloc(sizeof *array);
array->size = 0;
array->capacity = capacity;
array->data = dataPtr;
return array;
And remember to free()
this memory in your destructor function (dn_destroy()
).
并记住在析构函数(dn_destroy())中释放()这个内存。
#2
It seems that you mix up how you interpret your sizes and capacities. You use them as if the count the number of elements but you allocate them (with realloc
) as number of bytes. Change your code to the following:
您似乎混淆了解释尺寸和容量的方式。您可以像计算元素数一样使用它们,但是将它们(使用realloc)分配为字节数。将您的代码更改为以下内容:
int *dataPtr = realloc(a->data, 2*a->capacity*sizeof(a->data[0]));
#1
In your dn_new()
you have:
在你的dn_new()中你有:
if (dataPtr != NULL) {
struct DynamicArray array = { 0, capacity, dataPtr };
return &array;
}
Here, array
is a local variable; it will be out of scope after returning it. You should allocate memory on the heap for that:
这里,array是一个局部变量;返回后它将超出范围。您应该为堆分配内存:
struct DynamicArray *array = malloc(sizeof *array);
array->size = 0;
array->capacity = capacity;
array->data = dataPtr;
return array;
And remember to free()
this memory in your destructor function (dn_destroy()
).
并记住在析构函数(dn_destroy())中释放()这个内存。
#2
It seems that you mix up how you interpret your sizes and capacities. You use them as if the count the number of elements but you allocate them (with realloc
) as number of bytes. Change your code to the following:
您似乎混淆了解释尺寸和容量的方式。您可以像计算元素数一样使用它们,但是将它们(使用realloc)分配为字节数。将您的代码更改为以下内容:
int *dataPtr = realloc(a->data, 2*a->capacity*sizeof(a->data[0]));