为什么这里会报错?
请问为什么会这样报错啊?#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType; // 把int替换成了Elemtype
typedef struct LinkList
{
ElemType elem; // 存储整形元素
struct LinkList *next; // 指向直接后继元素的指针
} LinkList; // 等同于用typedef把struct LinkList定义成Linklist就不需要再输入struct LinkList,可以直接输入LinkList
void InitList(LinkList *L); // 初始化链表声明
void CreateList(LinkList *L, ElemType a[], ElemType n); // 创建链表声明
ElemType ListInsert(LinkList *L, ElemType i, ElemType e); // 链表插入声明
ElemType ListDelete(LinkList *L, ElemType i); // 删除链表声明
void printlist(LinkList *headpoint); // 打印输出表中元素
int main(void)
{
LinkList head; // 头结点
LinkList *headpoint = &head; // 指向头结点的指针(结构体变量并不指向结构体,所以需要声明结构体指针)
ElemType elements, n = 0, insertposition1, insertvalue1, insertposition2, insertvalue2, delete1, delete2; //
InitList(headpoint);
printf("##创建链表##\n\n");
printf("请输入链表中元素值,以空格分隔(如,从键盘上依次输入21 18 30 75 42 56):");
for (int i = 0; i < MaxSize; i++)
{
scanf("%d", &elements);
n++;
if (getchar() == '\n')
{
break;
}
}
CreateList(headpoint, elements, n);
printlist(headpoint); // 输出各元素的值
putchar('\n');
printf(
"\n##插入操作##\n\n"
"请输入第一次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):");
scanf("%d %d", &insertposition1, &insertvalue1);
if (ListInsert(headpoint, insertposition1, insertvalue1))
{
printf("在第%d个位置插入%d成功\n", insertposition1, insertvalue1);
}
else
{
printf("在第%d个位置插入%d失败,插入位置不合法\n", insertposition1, insertvalue1);
}
printlist(headpoint);
putchar('\n');
printf(
"请输入第二次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):");
scanf("%d %d", &insertposition2, &insertvalue2);
if (ListInsert(headpoint, insertposition2, insertvalue2))
{
printf("在第%d个位置插入%d成功\n", insertposition2, insertvalue2);
}
else
{
printf("在第%d个位置插入%d失败,插入位置不合法\n", insertposition2, insertvalue2);
}
printlist(headpoint);
putchar('\n');
printf(
"\n##删除操作##\n\n"
"请输入第一次要删除元素的位置(如 2 表示删除第2个位置的数值):");
scanf("%d", &delete1);
if (ListDelete(headpoint, delete1))
{
printf("删除第%d个数据元素成功\n", delete1);
}
else
{
printf("删除第%d个数据元素失败,删除位置不合法\n", delete1);
}
printlist(headpoint);
putchar('\n');
printf(
"\n请输入第二次要删除元素的位置(如 2 表示删除第2个位置的数值):");
scanf("%d", &delete2);
if (ListDelete(headpoint, delete2))
{
printf("删除第%d个数据元素成功\n", delete2);
}
else
{
printf("删除第%d个数据元素失败,删除位置不合法\n", delete2);
}
printlist(headpoint);
putchar('\n');
while (headpoint != NULL) // 为了防止内存泄漏,最后进行内存释放
{
LinkList *temp = headpoint;
headpoint = headpoint->next;
free(temp);
}
printf("\n=====顺序表初始化、插入,删除等操作已完成,程序结束!=====\n\n");
system("pause");
return 0;
}
void InitList(LinkList *L) /* 初始化链表 */
{
L = (struct LinkList *)malloc(sizeof(struct LinkList *));
L->next = NULL;
}
void CreateList(LinkList *L, ElemType a[], int n) /*创建链表 */
{
LinkList *pre = L;
int i;
for (i = n - 1; i >= 0; i--)
{
LinkList *t = (struct LinkList *)malloc(sizeof(struct LinkList *));
t->elem = a;
t->next = NULL;
pre->next = t;
pre = pre->next;
}
}
int ListInsert(LinkList *L, int i, ElemType e) /*按i位置插入元素*/
{
int j = 0;
LinkList *p = L;
while (p && (j < i - 1))
{
p = p->next;
j++;
}
if (!p || (j > i - 1))
return 0;
LinkList *t = (struct LinkList *)malloc(sizeof(struct LinkList *));
t->elem = e;
t->next = p->next;
p->next = t;
return 1;
}
int ListDelete(LinkList *L, int i) /*删除某个位置的元素*/
{
int j = 0;
LinkList *p = L;
LinkList *del = NULL;
while ((p->next) && (j < i - 1))
{
p = p->next;
j++;
}
if (!(p->next) || (j > i - 1))
{
return 0;
}
del = p->next;
p->next = del->next;
free(del);
return 1;
}
void printlist(LinkList *headpoint) // 打印输出表中元素
{
printf("\n当前表中元素如下\n");
LinkList *p = headpoint->next;
putchar('{');
while (p != NULL)
{
printf("%d ", p->elem);
p = p->next;
}
putchar('}');
} 您的代码中存在一些问题,导致了错误。以下是我发现的一些问题:
1. 在 InitList 和 CreateList 函数中,您使用 malloc 分配内存时,应该使用 sizeof(struct LinkList) 而不是 sizeof(struct LinkList *)。因为您需要的是一个 LinkList 结构体的大小,而不是指针的大小。
2. 在 InitList 函数中,您试图修改传入的指针 L,但是这个修改在函数外部是不可见的。因为在 C 语言中,函数参数是通过值传递的,所以您不能直接修改传入的指针。如果您想要修改传入的指针,您需要传入指针的指针。
以下是修改后的代码:
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType;
typedef struct LinkList {
ElemType elem;
struct LinkList *next;
} LinkList;
void InitList(LinkList **L);
void CreateList(LinkList *L, ElemType a[], ElemType n);
ElemType ListInsert(LinkList *L, ElemType i, ElemType e);
ElemType ListDelete(LinkList *L, ElemType i);
void printlist(LinkList *headpoint);
int main(void) {
LinkList *headpoint = NULL;
InitList(&headpoint);
// ... 其他代码保持不变
}
void InitList(LinkList **L) {
*L = (struct LinkList *)malloc(sizeof(struct LinkList));
(*L)->next = NULL;
}
void CreateList(LinkList *L, ElemType a[], int n) {
LinkList *pre = L;
int i;
for (i = n - 1; i >= 0; i--) {
LinkList *t = (struct LinkList *)malloc(sizeof(struct LinkList));
t->elem = a[ i];
t->next = NULL;
pre->next = t;
pre = pre->next;
}
}
// ... 其他函数保持不变
这样修改后,您的代码应该可以正常运行了。
请注意,本回答来自GPT-4
如果问题已经解决,请设置最佳答案 你好,根据代码和错误信息来看,可能是以下几个问题导致了报错:
1. ElemType没有定义。在代码中,ElemType是通过typedef定义的,可以尝试将其改为int。
2. malloc()分配内存失败。在代码中,InitList()函数中的malloc()分配内存的语句可能出现了错误。你可以检查一下是否有足够的内存可用。
3. 传入参数的类型不正确。如果使用了错误的参数类型调用函数,则会导致程序崩溃或结果出错。你可以检查一下函数声明和参数类型是否一致,以及传入的参数是否符合函数参数类型的要求。
希望这些信息能帮助你解决问题!
球一个最佳答案谢谢啦!这对我非常重要!{:10_254:}{:10_254:}{:10_254:} 这段代码中会报错的原因是在初始化链表的函数InitList中,传入的参数是指针类型LinkList *L ,但是在函数内部重新为L分配了内存,导致原本传入的指针所指向的内存被覆盖,最终导致程序运行时出现了错误。
为了解决这个问题,可以将InitList函数改为传入指向指针的指针类型,即LinkList **L ,这样可以在函数内部直接修改指针所指向的内存,而不会覆盖原本传入的指针。
修改后的InitList函数代码如下:
void InitList(LinkList **L) /* 初始化链表 */
{
*L = (struct LinkList *)malloc(sizeof(struct LinkList)); // 修改为 *L
(*L)->next = NULL; // 修改为 (*L)->next
}
同时,在main函数中调用InitList函数时需要传入指向指针的指针,即&headpoint 。
修改后的main函数代码如下:
int main(void)
{
LinkList head;
LinkList *headpoint = &head;
ElemType elements, n = 0, insertposition1, insertvalue1, insertposition2, insertvalue2, delete1, delete2;
InitList(&headpoint); // 修改为传入指向指针的指针
printf("##创建链表##\n\n");
printf("请输入链表中元素值,以空格分隔(如,从键盘上依次输入21 18 30 75 42 56):");
for (int i = 0; i < MaxSize; i++)
{
scanf("%d", &elements[ i]);
n++;
if (getchar() == '\n')
{
break;
}
}
CreateList(headpoint, elements, n);
printlist(headpoint); // 输出各元素的值
putchar('\n');
printf(
"\n##插入操作##\n\n"
"请输入第一次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):");
scanf("%d %d", &insertposition1, &insertvalue1);
if (ListInsert(headpoint, insertposition1, insertvalue1))
{
printf("在第%d个位置插入%d成功\n", insertposition1, insertvalue1);
}
else
{
printf("在第%d个位置插入%d失败,插入位置不合法\n", insertposition1, insertvalue1);
}
printlist(headpoint);
putchar('\n');
printf(
"请输入第二次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):");
scanf("%d %d", &insertposition2, &insertvalue2);
if (ListInsert(headpoint, insertposition2, insertvalue2))
{
printf("在第%d个位置插入%d成功\n", insertposition2, insertvalue2);
}
else
{
printf("在第%d个位置插入%d失败,插入位置不合法\n", insertposition2, insertvalue2);
}
printlist(headpoint);
putchar('\n');
printf(
"\n##删除操作##\n\n"
"请输入第一次要删除元素的位置(如 2 表示删除第2个位置的数值):");
scanf("%d", &delete1);
if (ListDelete(headpoint, delete1))
{
printf("删除第%d个数据元素成功\n", delete1);
}
else
{
printf("删除第%d个数据元素失败,删除位置不合法\n", delete1);
}
printlist(headpoint);
putchar('\n');
printf(
"\n请输入第二次要删除元素的位置(如 2 表示删除第2个位置的数值):");
scanf("%d", &delete2);
if (ListDelete(headpoint, delete2))
{
printf("删除第%d个数据元素成功\n", delete2);
}
else
{
printf("删除第%d个数据元素失败,删除位置不合法\n", delete2);
}
printlist(headpoint);
putchar('\n');
while (headpoint != NULL) // 为了防止内存泄漏,最后进行内存释放
{
LinkList *temp = headpoint;
headpoint = headpoint->next;
free(temp);
}
printf("\n=====顺序表初始化、插入,删除等操作已完成,程序结束!=====\n\n");
system("pause");
return 0;
}
不行,都不行,哎 应该是free的时候发生访问非法指针的错误。你是运行时错误还是编译错误? 我知道了。
请你看一下代码的第18行:
LinkList *headpoint = &head;
可以发现,这里的 headpoint 变量并不是用 malloc 动态申请的内存空间指针,而是一个静态的指针。所以是不能被 free 函数删除的。
所以只需删除 headpoint 指向的一系列动态内存空间即可。
修改后的代码(仅修改主函数最后几句)
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType; // 把int替换成了Elemtype
typedef struct LinkList
{
ElemType elem; // 存储整形元素
struct LinkList *next; // 指向直接后继元素的指针
} LinkList; // 等同于用typedef把struct LinkList定义成Linklist就不需要再输入struct LinkList,可以直接输入LinkList
void InitList(LinkList *L); // 初始化链表声明
void CreateList(LinkList *L, ElemType a[], ElemType n); // 创建链表声明
ElemType ListInsert(LinkList *L, ElemType i, ElemType e); // 链表插入声明
ElemType ListDelete(LinkList *L, ElemType i); // 删除链表声明
void printlist(LinkList *headpoint); // 打印输出表中元素
int main(void)
{
LinkList head; // 头结点
LinkList *headpoint = &head; // 指向头结点的指针(结构体变量并不指向结构体,所以需要声明结构体指针)
ElemType elements, n = 0, insertposition1, insertvalue1, insertposition2, insertvalue2, delete1, delete2; //
InitList(headpoint);
printf("##创建链表##\n\n");
printf("请输入链表中元素值,以空格分隔(如,从键盘上依次输入21 18 30 75 42 56):");
for (int i = 0; i < MaxSize; i++)
{
scanf("%d", &elements);
n++;
if (getchar() == '\n')
{
break;
}
}
CreateList(headpoint, elements, n);
printlist(headpoint); // 输出各元素的值
putchar('\n');
printf(
"\n##插入操作##\n\n"
"请输入第一次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):");
scanf("%d %d", &insertposition1, &insertvalue1);
if (ListInsert(headpoint, insertposition1, insertvalue1))
{
printf("在第%d个位置插入%d成功\n", insertposition1, insertvalue1);
}
else
{
printf("在第%d个位置插入%d失败,插入位置不合法\n", insertposition1, insertvalue1);
}
printlist(headpoint);
putchar('\n');
printf(
"请输入第二次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):");
scanf("%d %d", &insertposition2, &insertvalue2);
if (ListInsert(headpoint, insertposition2, insertvalue2))
{
printf("在第%d个位置插入%d成功\n", insertposition2, insertvalue2);
}
else
{
printf("在第%d个位置插入%d失败,插入位置不合法\n", insertposition2, insertvalue2);
}
printlist(headpoint);
putchar('\n');
printf(
"\n##删除操作##\n\n"
"请输入第一次要删除元素的位置(如 2 表示删除第2个位置的数值):");
scanf("%d", &delete1);
if (ListDelete(headpoint, delete1))
{
printf("删除第%d个数据元素成功\n", delete1);
}
else
{
printf("删除第%d个数据元素失败,删除位置不合法\n", delete1);
}
printlist(headpoint);
putchar('\n');
printf(
"\n请输入第二次要删除元素的位置(如 2 表示删除第2个位置的数值):");
scanf("%d", &delete2);
if (ListDelete(headpoint, delete2))
{
printf("删除第%d个数据元素成功\n", delete2);
}
else
{
printf("删除第%d个数据元素失败,删除位置不合法\n", delete2);
}
printlist(headpoint);
putchar('\n');
headpoint=headpoint->next;
while (headpoint != NULL) // 为了防止内存泄漏,最后进行内存释放
{
LinkList *temp = headpoint;
headpoint = headpoint->next;
free(temp);
}
printf("\n=====顺序表初始化、插入,删除等操作已完成,程序结束!=====\n\n");
system("pause");
return 0;
}
void InitList(LinkList *L) /* 初始化链表 */
{
L = (struct LinkList *)malloc(sizeof(struct LinkList *));
L->next = NULL;
}
void CreateList(LinkList *L, ElemType a[], int n) /*创建链表 */
{
LinkList *pre = L;
int i;
for (i = n - 1; i >= 0; i--)
{
LinkList *t = (struct LinkList *)malloc(sizeof(struct LinkList *));
t->elem = a;
t->next = NULL;
pre->next = t;
pre = pre->next;
}
}
int ListInsert(LinkList *L, int i, ElemType e) /*按i位置插入元素*/
{
int j = 0;
LinkList *p = L;
while (p && (j < i - 1))
{
p = p->next;
j++;
}
if (!p || (j > i - 1))
return 0;
LinkList *t = (struct LinkList *)malloc(sizeof(struct LinkList *));
t->elem = e;
t->next = p->next;
p->next = t;
return 1;
}
int ListDelete(LinkList *L, int i) /*删除某个位置的元素*/
{
int j = 0;
LinkList *p = L;
LinkList *del = NULL;
while ((p->next) && (j < i - 1))
{
p = p->next;
j++;
}
if (!(p->next) || (j > i - 1))
{
return 0;
}
del = p->next;
p->next = del->next;
free(del);
return 1;
}
void printlist(LinkList *headpoint) // 打印输出表中元素
{
printf("\n当前表中元素如下\n");
LinkList *p = headpoint->next;
putchar('{');
while (p != NULL)
{
printf("%d ", p->elem);
p = p->next;
}
putchar('}');
}
运行结果
##创建链表##
请输入链表中元素值,以空格分隔(如,从键盘上依次输入21 18 30 75 42 56):21 18 30 75 42 56
当前表中元素如下
{56 42 75 30 18 21 }
##插入操作##
请输入第一次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):2 2
在第2个位置插入2成功
当前表中元素如下
{56 2 42 75 30 18 21 }
请输入第二次要插入的位置和插入的数值(插入位置和插入数值之间以空格相隔,如2 5,表示第2个位置插入数值5):5 5
在第5个位置插入5成功
当前表中元素如下
{56 2 42 75 5 30 18 21 }
##删除操作##
请输入第一次要删除元素的位置(如 2 表示删除第2个位置的数值):2
删除第2个数据元素成功
当前表中元素如下
{56 42 75 5 30 18 21 }
请输入第二次要删除元素的位置(如 2 表示删除第2个位置的数值):5
删除第5个数据元素成功
当前表中元素如下
{56 42 75 5 18 21 }
=====顺序表初始化、插入,删除等操作已完成,程序结束!=====
请按任意键继续. . . 额外减小 发表于 2023-10-15 20:09
我知道了。
请你看一下代码的第18行:
感谢大佬!!!!! 额外减小 发表于 2023-10-15 20:09
我知道了。
请你看一下代码的第18行:
大佬,我还有一点不是很清楚,就是代码的第115和第134行,它必须得删掉sizeof(struct LinkList *)中的*才能正常运行,不然在free的时候就会报错 1613551 发表于 2023-10-15 20:56
大佬,我还有一点不是很清楚,就是代码的第115和第134行,它必须得删掉sizeof(struct LinkList *)中的* ...
对。因为指针指向的是一个 struct LinkList 变量,那就是申请一个 sizeof(struct LinkList)的动态内存空间。
页:
[1]