问题 1:函数名拼写错误导致链接错误
如:函数声明为 void intiDynamicList(...)
(拼写错误为 intiDynamicList
),但调用时使用 initDynamicList
。
正确使用函数拼写,仔细检查。避免因为敲打输入过快而导致,函数声明时和定义时的函数在个别字母上错乱位置而导致函数拼写的不一致。
问题 2:realloc
使用不当导致内存泄漏
-
错误现象:
realoc="创建返回 int"
(实际是realloc
未正确处理返回值) -
原因:直接覆盖
list->elements
,若realloc
失败会丢失原指针,导致内存泄漏
修正后代码:
问题 3:扩容逻辑错误
-
错误现象:在
dynamicInsert
中错误调用resizeDynamicList(&list)
。 -
原因:
list
本身已是指针,传递&list
会导致二级指针错误。
问题 4:未检查 malloc
返回值
-
错误现象:
malloc
分配内存后未检查是否成功。 -
风险:如果内存不足,
malloc
返回NULL
,直接使用会导致程序崩溃。
修正代码:用if语言判断是否会产生NULL
问题 5:变量作用域问题
-
错误现象:
case 3
中直接声明int pos
导致编译错误。 -
原因:C 语言中
switch-case
的case
内直接声明变量需用大括号包裹。
修正代码:添加一对大括号,VS2022本身不会报错,似乎也可以正常运行,deepseek建议加大括号。鄙人学术尚浅,问题有待进一步了解。
完整代码:
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
typedef struct
{
int* elements; //元素
int size; // 长度
int capacity; // 容量
}DynamicList;
// 初始化顺序表函数
void initDynamicList(DynamicList* list, int initSize)
{
list->capacity = initSize * 2;
// 预留了一部分额外的空间,使得在添加新元素时不需要每次都重新分配内存,从而提升性能。
// 例如,如果初始大小是10,那么容量是20,这样在添加前10个元素时不需要扩容,只有超过10个时才需要调整容量。
list->elements = (int*)malloc(list->capacity * sizeof(int)); // 一个元素占4个字节
// `elements`是指向动态数组内存块的指针。
// 通过`malloc`分配内存后,返回的是指向这块内存的指针,需要将这个指针赋值给`elements`,
// 这样后续可以通过`elements`访问和操作数组中的元素。
if (list->elements == NULL) {
printf("内存分配失败!\n");
exit(1); // 退出程序或处理错误
}
list->size = initSize;
for (int i = 0; i < list->size; i++)
{
list->elements[i] = 0;
}
}
// 扩容函数
void resizeDynamicList(DynamicList* list)
{
int new_capacity=list->capacity * 2;
int*new_elements = (int*)realloc(list->elements, new_capacity * sizeof(int));
if (new_elements == NULL)
{
printf("内存分配失败!\n");
exit(1);
}
list->elements = new_elements;
list->capacity = new_capacity;
printf("已经扩容 %d\n", list->capacity);
}
// 插入函数
bool dynamicInsert(DynamicList* list, int position, int value)
{
// 先判断有没有满容,再判断有没有不规范输入
if (list->size >= list->capacity)
{
printf("顺序表已满:进行扩容\n");
resizeDynamicList(list); // 这里本身就是用指针用接受的,不需要取地址&
}
if (position<1 || position>list->size + 1)
{
printf("非法插入\n");
return false;
}
for (int i = list->size; i >= position; i--) // 不能只> 防止取到边界size
{
list->elements[i] = list->elements[i - 1]; // 逐个后移
}
list->elements[position - 1] = value;
list->size++;
return true;
}
// 删除函数
bool dynamicDelete(DynamicList* list, int position)
{
if (position<1 || position>list->size)
{
printf("非法删除位置!\n");
return false;
}
for (int i = position - 1; i < list->size - 1; i++) // size-1为数组边界 不取=
{
list->elements[i] = list->elements[i + 1]; // 逐个前移
}
list->size--;
return true;
}
// 查找元素
int dynamicSearch(DynamicList* list, int value)
{
for (int i = 0; i < list->size; i++)
{
if (list->elements[i] == value)
{
return (i + 1);
}
}
return -1;
}
// 显示函数
void displayDynamicList(DynamicList* list)
{
printf("当前顺序表:[");
for (int i = 0; i < list->size; i++)
{
printf("%d", list->elements[i]);
if (i != list->size - 1)
{
printf(", ");
}
}
printf("](容量:%d)\n", list->capacity);
}
int main()
{
DynamicList list; //定义一个结构体list
initDynamicList(&list, 10); // 初始化顺序表函数
int choice, position, value;
while (1)
{
printf("\n动态数组顺序表操作菜单:\n");
printf("-----1.插入元素--------2.删除元素---------------\n");
printf("-----3.查找元素--------4.显示顺序表-------------\n");
printf("-----0.退出-------------------------------------\n");
printf("------------------------------------------------\n");
printf("请输入操作数:>");
scanf_s("%d", &choice);
switch (choice)
{
case 1:
printf("输入插入位置和值(例:3 5):>");
scanf_s("%d %d", &position, &value);
dynamicInsert(&list, position, value); // 插入函数
break;
case 2:
printf("输入删除位置:>");
scanf_s("%d", &position);
dynamicDelete(&list, position);
break;
case 3:
{
printf("请输入查找的值:");
scanf_s("%d", &value);
int pos = dynamicSearch(&list, value);
if (pos != -1)
{
printf("找到元素,位置为:>%d\n", pos);
}
else
{
printf("未找到该元素\n");
}
break;
}
case 4:
displayDynamicList(&list);
break;
case 0:
free(list.elements); // 调用了malloc函数完之后记得释放空间
return 0;
default:
printf("无效输入请重新选择:>");
break;
}
}
return 0;
}
感谢您的观看,虚心接受大家的指点与建议。渴望见到更多不同形式代码的实现。❀❀
修正代码: 本来就是用DynamicList * list 指针来接受的,指针本身就是一个地址,&去掉即可。