gpt4 book ai didi

c - 为什么使用指针到指针会出现内存访问冲突错误

转载 作者:行者123 更新时间:2023-11-30 16:27:51 24 4
gpt4 key购买 nike

我用 C 创建了一个小程序来测试指针到指针。

当我使用函数(第 39 行)打印列表数据时,将项目添加到列表后出现错误 3221225477。但是,当我注释第 39 行并从第 59 行删除注释时,程序可以正常工作通常情况下。

如果程序从上到下运行,为什么我会从操作系统(在本例中为 Windows)收到 ACCESS_VIOLATION 错误?

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


struct employee{
int id;
char name[50];
char street[50];
};

typedef struct element* List;

struct element{
struct employee data;
struct element *next;
};

typedef struct element Elem;

List* list_create();
void list_print(List* list);
int list_is_empty(List* list);
int list_add(List* list, struct employee a);

int main(){

List* list = list_create();

struct employee a1;
a1.id = 10;
strcpy(a1.name, "John");
strcpy(a1.street, "Address XYZ");

list_add(list, a1);
//Sleep(5000); small pause, I thinking it might have something to do with thread.

//list_print(list); // *****line--39 *****;

return 0;

}

List* list_create(){
List* li = (List *) malloc(sizeof(List));
if(li != NULL)
*li = NULL;
return li;
}

int list_add(List* list, struct employee emp){

Elem* n1 = (Elem *) malloc(sizeof(Elem));
n1->data = emp;
n1->next = *list;
list = &n1;

list_print(list); // *****line--59 *****;

}

void list_print(List* list){

Elem aux = **list;
printf(" **lista Id: %d\n", aux.data.id);
printf(" **lista name: %s\n", aux.data.name);
printf(" **lista name: %s\n", aux.data.street);

}

最佳答案

C 是按值传递,而不是按引用传递。因此,List* list在函数 list_add 中和 List* listmain引用内存中的两个不同位置(它们最初指向 list_add 开头的相同位置,但它们是两个不同的指针,最初具有相同的值,而不是相同的指针):修改变量 list 的值list_add内不影响 list 的值在main .

具体来说:

list = &n1list_add仅修改 list 的值在该函数内,即复制到 list_add 的参数值调用时的堆栈帧。但是,当您尝试在第 59 行打印它时,仍然在 list_add 范围内。 ,可以看到更改后的值,因此是打印出来的指针,按您的预期工作。

当您尝试打印 list 时第 39 行,main ,另一方面,变量 list main内函数的值没有被赋值 list = &n1 改变就在 list_add 中的第 39 行之前,因为这只改变了该函数范围内副本的值。因此在这种情况下list_print尝试打印空列表的元素(因为 list 的值仍然是 list_create 返回的值,它是指向 NULL 指针的指针,因此 Elem aux = **list 从而取消引用 list 然后尝试取消引用 NULL 指针),从而导致无效的内存访问。

这段代码中的问题不在于列表打印的位置,而在于 list_add没有正确更新列表。在解决此问题时,您需要考虑到它只能通过修改作为参数接收的引用值所指向的内容来修改列表结构,而不是尝试修改指针本身。如果你确实想修改地址list指向 main从函数内部 list_add (例如 list = &n1 行似乎试图执行的操作),您需要将指针传递给 list进入list_add ,而不仅仅是指针 list本身。

代码本身似乎还存在其他问题(例如, list_print 仅打印一个元素,并且没有打印空列表的处理,这就是导致此处错误成为实际无效内存访问而不仅仅是调用 list_add 后错误地将列表留空),但上述问题是导致此特定问题的原因。

关于c - 为什么使用指针到指针会出现内存访问冲突错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52620236/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com