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
函数中,您实际上需要为向量分配内存。
您还需要做以下事情:
- 在
initVector
returnv
而不是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就插入成功了。
我添加到您的测试代码以显示 vect
和 vect->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
● 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
函数中,您实际上需要为向量分配内存。
您还需要做以下事情:
- 在
initVector
returnv
而不是v->data
或&v
- 在
vectorInsert
中打印array->data[index].value
而不是array->data[index]
- 在
vectorInsert
return1
成功时,在您的分配中添加错误检查并在内存错误中添加 return0
。
除原始 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就插入成功了。
我添加到您的测试代码以显示 vect
和 vect->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