复制结构的组件会删除同一结构的另一个组件

标签 c pointers struct

我目前正在学习 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/

相关文章:

与实际类型已知的 void 指针比较

c++ - 引用指针的可选参数?

c++ - 多级指针作为参数 C++

C 全局匿名结构/union

c - 无法在 C 中正确使用结构指针

c - 错误: function declared 'ms_abi' here was previously declared without calling convention (clang)

c - 仅当参数不是常量时,math.h 中的 sqrt 才会导致链接器错误 "undefined reference to sqrt"

c - 如何使用C从Xml中获取属性值

c - C 中的二叉搜索树插入函数

c - 指向字符数组指针的指针