C 导致访问冲突的指针逻辑
添加联系人的程序方法之一是在执行时出现以下错误:C 导致访问冲突的指针逻辑,c,pointers,memory-management,data-structures,C,Pointers,Memory Management,Data Structures,添加联系人的程序方法之一是在执行时出现以下错误: Unhandled exception at 0x00111deb in G00290342.exe: 0xC0000005: Access violation reading location 0x00000050. 我研究了这个错误,发现它是由访问已经在使用的内存引起的。我已经把它缩小到readFile方法中导致“curr”变量为空的指针逻辑 它正在破坏的代码如下所示: while(curr->next != NULL) {
Unhandled exception at 0x00111deb in G00290342.exe: 0xC0000005: Access violation reading location 0x00000050.
我研究了这个错误,发现它是由访问已经在使用的内存引起的。我已经把它缩小到readFile方法中导致“curr”变量为空的指针逻辑
它正在破坏的代码如下所示:
while(curr->next != NULL)
{
curr = curr->next;
}
这是供参考的完整方法:
int addContact(struct contact *theList)
{
struct contact *newContact, *curr;
char fn[15],sn[15],ph[15],cmpy[15],eml[15];
//create the new structure
newContact = (struct contact *)malloc(sizeof(struct contact));
if(newContact == NULL)
{
return(0);
}
//find the end of list
curr = theList;
//scroll through the list
while(curr->next != NULL)
{
curr = curr->next;
}
//now have the last contact and the new one here
printf("\nEnter a surname: ");
gets(newContact->sname);
printf("\nEnter a first name: ");
gets(newContact->fname);
printf("\nEnter a phone: ");
gets(newContact->phone);
printf("\nEnter a company: ");
gets(newContact->company);
printf("\nEnter an email: ");
gets(newContact->email);
//add the new contact to the end of the list
curr->next = newContact;
newContact->prev = curr;
newContact->next = NULL;
return(0);
}//end addContact
这是我读取测试文件的主要方法:
main()
{
int sts,iChoice;
struct contact *ptrList, *head;
//head of sorted list
struct contact *srtdList;
srtdList = NULL;
ptrList = NULL;
ptrList = readFile("test.csv",ptrList);
head = ptrList;
/////menu for options
system("cls");
printf("\n\n\t\tWelcome to BV Contact Organizer\n\n");
printf("\n\n\t\tEnter a number ranging from 1 to 6 for options.\n\n");
printf("\n\t\t1. Search");
printf("\n\t\t2. Add");
printf("\n\t\t3. Sort");
printf("\n\t\t4. Remove");
printf("\n\t\t5. Edit");
printf("\n\t\t6. Exit");
printf("\n\n\t\tEnter your menu choice: ");
fflush(stdin);
scanf("%d", &iChoice);
// user enters one of 6 values:
// Search,add,sort,remove,exit or edit contacts
switch(iChoice)
{
case 1: // Add
{
sts = addContact(head);
sts = writeListToFile("test.csv",head);
while(ptrList != NULL)
{
printf("\n%s,%s,%s,%s,%s",ptrList->sname,ptrList->fname,ptrList->phone,ptrList->company,ptrList->email);
ptrList = ptrList->next;
}
break;
}
case 2: // Sort
{
//return the head of the sorted list to here
srtdList = sortList(head,srtdList);
head = srtdList;
if(srtdList != NULL)
{
printf("\n\nSorted List");
while(srtdList != NULL)
{
printf("\n%s,%s,%s,%s,%s",srtdList->sname,srtdList->fname,srtdList->phone,srtdList->company,srtdList->email);
srtdList = srtdList->next;
}
sts = writeListToFile("testSort.csv",head);
}
else
{
printf("nothing to print");
}
printf("\n\n\n");
system("pause");
break;
}
case 3: // Exit
{
printf("\n\nProgram exiting!...");
break;
}
default:
{
printf("\n\nInvalid menu choice,please choose a number ranging from 1 to 6!...");
}
}//end of switch
return(iChoice);
} // end of main
这是请求的结构联系人定义:
struct contact {
char sname[15];
char fname[15];
char phone[15];
char company[15];
char email[15];
struct contact *prev;
struct contact *next;
};
这是用于读取文件的方法,导致以下问题:
struct contact *readFile(char * FName,struct contact *ptrList)
{
struct contact *head, *newContact;
FILE *fptr;
char oneLine[60];
char *sname, *fname, *phone,*company, *email;
head = ptrList;
fptr = fopen(FName,"r");
if(fptr == NULL)
{
printf("\nCant open file!");
return(ptrList);
}
fgets(oneLine, 55, fptr);
while(!feof(fptr))
{
fgets(oneLine, 55, fptr);
if(oneLine[strlen(oneLine)-1] == '\n')
{
oneLine[strlen(oneLine)-1] = '\0';
}
sname = strtok(oneLine,",");
fname = strtok(NULL,",");
phone = strtok(NULL,",");
company = strtok(NULL,",");
email = strtok(NULL,",");
if(head == NULL)
{
head = (struct contact *)malloc(sizeof(struct contact));
ptrList = head;
strcpy(head->sname,sname);
strcpy(head->fname,fname);
strcpy(head->phone,phone);
strcpy(head->company,company);
strcpy(head->email, email);
head->prev = NULL;
head->next = NULL;
}
else
{
newContact = (struct contact *)malloc(sizeof(struct contact));
head->next = newContact;
newContact->prev = head;
newContact->next = NULL;
//copy the data to the new one
strcpy(head->sname,sname);
strcpy(head->fname,fname);
strcpy(head->phone,phone);
strcpy(head->company,company);
strcpy(head->email,email);
//move down the list so that the head variable
//points to the last contact
head = newContact;
}
}//end while
fclose(fptr);
return(ptrList);
}
它显示
访问冲突读取位置0x00000050
,因此您试图读取的内存位置实际上是一些垃圾值。从一开始就跟踪列表值,无论您在哪里分配内存,都要立即执行memset(newContact,0,sizeof(struct contact))
。在所有这些之后,如果您仍然面临问题,请提供代码,可能存在逻辑问题,因此您将curr
分配给列表
,而不进行任何NULL
检查:
curr = theList;
因此,当您到达而时,如果curr
确实为NULL
,则当您尝试执行curr->next
时,将发生访问冲突:
while(curr->next != NULL)
{
curr = curr->next;
}
如果列表中的最后一个元素为非空
并且指向垃圾内存位置您确定curr
不是空
吗?因为它看起来就是这样的。这里的0x00000050
与NULL
之间似乎有一些偏移。您没有检查“列表”是否为NULL。如果是,while循环将失败。至少要声明它。在尝试遍历该列表之前,您可能需要检查该列表是否为空,因为新分配的节点应该成为新的列表头(如果为空)。此外,由于报告的值不是0x00000000
,很可能您没有正确地将列表头初始化为NULL,这是另一个逻辑错误。最后,您需要通过地址(意味着双指针)传入列表头,或者始终返回真正的列表头作为函数结果,否则您将永远无法正确设置外部列表头。。似乎这还不够,不要使用get()
。该函数在安全性方面非常糟糕,已从该语言中弃用,将不会包含在下一个标准中。改用fgets()
。因为你正在更新你的问题帖子,你是否也可以添加struct contact
的结构定义?@WhozCraig我认为它是0x00000050
,因为这是contact
对象中next
的偏移量。这是我的答案:)-你的在prettier中,尽管+1Ya,我刚刚在curr=theList上添加了一个空检查;我的第二个问题是如何补救?@user2307951很难说,但我猜在readFile
中,您无法打开文件,返回ptrList
,它是NULL
,但是addContact
中应该有逻辑创建head
的位置,如果它没有初始化为Zcraig所说的您需要将list
作为双指针传递才能工作。读取readFile()
,将现有列表传递到函数中时会发生什么head
最初将被设置为ptrList
,它可能有一个next
指向列表的其余部分。然后,在第一个节点读取时,head->next=newContact
孤立所有经过初始ptrList
节点的内容,从而丢失(并泄漏)这些节点。您可能也想解决这个问题,或者不必费心让函数修改现有列表,只需删除ptrList
。正如目前所写的,它无论如何都不起作用。我不确定如何实现它?因此,它源于我的“readFile”方法。如果我去掉“ptrList”,我该怎么做?我尝试了memset代码段,但我得到一个错误,说类型contact的参数与类型int不兼容。我已经用我上面阅读列表的主方法更新了我的问题。对不起,键入:)在memset中我添加了memset代码段再次在mem分配之后。这个代码段到底是做什么的?如果您添加空检查,您将确保能够正确地检测到空列表或列表结尾。在方法的末尾,您添加了newContact->next=NULL代码>这使得这成为可能。现在,memset将malloc分配的整个内存设置为0。因此,即使您错过了它或其他一些地方,您可能仍然错过了它,memset已经对此进行了补偿,并且您的空检查仍然有效。基本上这是一个故障安全机制。酷,我刚刚在那里测试了它,它说“curr”没有初始化。我如何解决这个问题?好的,我解决了这个问题,结果是我的readFile方法,因为指针没有正确初始化。你能发现我的指针哪里出错了吗?上面的代码中有多个问题。1.在readFile
的else块
中,应将姓名、电话公司等的新值分配给newContact
而不是head
。2.在返回之前,您从未将任何内容分配给ptrList
。因此method
总是返回null
。这会导致内存问题
curr = theList;
while(curr->next != NULL)
{
curr = curr->next;
}