C 中的动态数组向量

Dynamic array Vector in C

● int vectorInsert(Vector * array, int index, Data value);

我在做

如果这可以根据给定的说法更正。

我用

调用它
Vector *vect = initVector();
Data data_array[20];
for(i = 0 ; i < 20 ; i++){
    data_array[i].value = (rand() % 20) + 1;
    vectorInsert(vect, i, data_array[i]);
}

在编译器中启用所有警告和调试信息(例如使用 gcc -Wall -g 编译)。然后它应该警告你

Vector * initVector(){
 Vector *v; /// UNINITALIZED
v->max_size=0;
v->current_size=0;
v->data = malloc(sizeof(int)*v->max_size);
return v->data;
//      return (&v);
} 

所以你有一个 undefined behavior, and that is awfully bad.

(当然编译器会给出很多其他警告,你应该改进你的代码,直到完全没有警告。然后你应该使用gdb调试器)

您可能想阅读有关 flexible array members 的内容。

考虑或许至少:

Vector* createVector(int maxsize) {
  if (maxsize<=0) 
    { fprintf(stderr, "bad maxsize=%d\n", maxsize); exit(EXIT_FAILURE); };
  Vector* v = malloc(sizeof(Vector));
  if (!v) { perror("malloc Vector"); exit(EXIT_FAILURE); };
  v->data = malloc(sizeof(Data)*maxsize);
  if (!v->data) { perror("malloc data"); exit(EXIT_FAILURE); };
  v->max_size = maxsize;
  v->current_size = 0;
  memset(v->data, 0, sizeof(Data)*maxsize);
  return v;
}

您的代码中有几个错误,但最重要的错误在您的 initVector 函数中,您实际上需要为向量分配内存。

您还需要做以下事情:

  • initVectorreturnv而不是v->data&v
  • vectorInsert 中打印 array->data[index].value 而不是 array->data[index]
  • vectorInsert return 1 成功时,在您的分配中添加错误检查并在内存错误中添加 return 0

除原始 malloc 之外的所有这些都是编译器发出的警告 return。

首先,根据您的说明,max_size 应该是一个无符号整数,所以我更改了 Vector 以反映这一点,使用 size_t。我还将相关格式说明符从 %d 更改为 %zu 以匹配此新类型。

您的 initVector() 函数需要为 Vector 分配内存,因此已将其添加。此外,这里不需要为 Data 结构的动态数组分配内存,因此 v->data 设置为 NULL。此函数还应 return 指向新分配的内存 v 的指针,而不是像您最初那样指向此 Vector.data 字段的指针。

vectorInsert() 函数中,您忽略了检查内存分配错误,因此我在尝试分配后添加了一个检查,如果有错误,returns 0。插入新的 Data 结构后,您对递增 .current_size 的检查是错误的。首先,你需要增加 if array->current_size <= index。接下来,您需要将 .current_size 加一,而不是将 .current_size 设置为比索引值大一。此外,在此处打印插入的值时,您忘记访问 .value 字段。我认为这可能是由于您对传递给 vectorInsert()Data 结构使用的混淆名称造成的。您将此结构称为 value,因此在上一行中我们有 array->data[index] = value,您将结构 value 分配给 array->data[index]。但是在对 printf() 的调用中,您想要显示结构 value 持有的值。选择更好的名字总是成功的!最后,这个函数returns 1就插入成功了。

我添加到您的测试代码以显示 vectvect->data 的内容,还添加了一个 Data 结构 test_insert 来测试插入到一个任意索引。

最后,在所有这一切之后你需要释放内存分配,所以我添加了几个对 free() 的调用。

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    int value;
}Data;

/* Specs say that max_size should be an unsigned integer */
typedef struct{
    size_t max_size; //initialize to 0
    size_t current_size; //initialize to 0
    Data *data;  // array of integers we're storing
} Vector;

/* Modified function */
Vector * initVector(void){
    Vector *v = malloc(sizeof(*v));
    v->max_size=0;
    v->current_size=0;
    v->data = NULL;
    return v;
}

int  vectorInsert(Vector * array, size_t index, Data value)
{
    if(index >= array->max_size)
    {
        array->max_size = index * 2 + 1; 
        printf("Inside Vect max_size is : %zu\n", array->max_size);

        Data *new_array = malloc(sizeof(Data) * array->max_size);

        /* Added check for allocation error */
        if (new_array == NULL)
            return 0;

        if(array->data != NULL)
        {
            memcpy(new_array, array->data, sizeof(Data)*array->current_size);
            free(array->data);
            array->data = NULL;
        }
        array->data = new_array;
    }

    array->data[index] = value;

    printf("Main : %d\n", array->data[index].value);

    /* Modified current_size increment logic */
    if(array->current_size <= index)
    {
        array->current_size += 1;
    }

    /* Successful insertion */
    return 1;
}

int main(void)
{
    size_t i;
    Vector *vect = initVector();
    Data data_array[20];
    Data test_insert = { -5 };      // to test index insertion

    for(i = 0 ; i < 20 ; i++){
        data_array[i].value = (rand() % 20) + 1;
        vectorInsert(vect, i, data_array[i]);
    }

    /* Display results */
    printf("vect->max_size = %zu\n", vect->max_size);
    printf("vect->current_size = %zu\n", vect->current_size);
    printf("vect->data contains:\n");
    for (i = 0; i < vect->current_size; i++)
        printf("%d ", vect->data[i].value);
    putchar('\n');

    /* Insert test_insert at index 5 */
    vectorInsert(vect, 5, test_insert);

    /* Display results */
    printf("vect->max_size = %zu\n", vect->max_size);
    printf("vect->current_size = %zu\n", vect->current_size);
    printf("vect->data contains:\n");
    for (i = 0; i < vect->current_size; i++)
        printf("%d ", vect->data[i].value);
    putchar('\n');

    /* Free memory allocations */
    free(vect->data);
    free(vect);

    return 0;
}

下面是结果示例:

vect->max_size = 31
vect->current_size = 20
vect->data contains:
4 7 18 16 14 16 7 13 10 2 3 8 11 20 4 7 1 7 13 17 

vect->max_size = 31
vect->current_size = 20
vect->data contains:
4 7 18 16 14 -5 7 13 10 2 3 8 11 20 4 7 1 7 13 17