导致访问冲突的指针逻辑

时间:2013-04-23 18:28:46

标签: c pointers memory-management data-structures

添加联系人的一种程序方法是在执行时出现以下错误:

Unhandled exception at 0x00111deb in G00290342.exe: 0xC0000005: Access violation reading location 0x00000050.

我已经研究过这个错误,发现它是由访问已经在使用的内存引起的。我已经将它缩小到我的readFile方法中的指针逻辑,导致'curr'变量为NULL。

它正在破解的代码在这里:

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;
};

这是用于readFile的方法并导致问题:

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);
}

3 个答案:

答案 0 :(得分:2)

因此,您要curr分配给theList而不进行任何NULL次检查:

curr = theList;

所以如果while确实是curr NULL,那么当您尝试curr->next时,您将遇到访问权限违规行为:

while(curr->next != NULL)
{
    curr = curr->next;
}

答案 1 :(得分:0)

它说Access violation reading location 0x00000050所以你试图读取一个实际上是垃圾值的内存位置。从头开始跟踪List值,无论你在哪里分配内存,立即执行memset(newContact,0,sizeof(struct contact))。毕竟,如果您仍然面临问题,请提供代码,可能存在逻辑问题

答案 2 :(得分:0)

curr = theList;    
 while(curr->next != NULL)
 {
    curr = curr->next;

}
如果theList中的最后一个元素是not null并指向垃圾内存位置

,也可能会出现此问题