2012-04-16 2 views
0

Visual Studio 2010에서 작성한 C 프로그램에서 처리되지 않은 win32 예외가 발생합니다.C 프로그래밍으로 처리되지 않은 win32 예외가 발생할 수 있습니다 (strlen 함수에서 발생할 수 있음).

디버거 출력을 기반으로 strlen 함수에 있다고 생각하지만 잘 모르겠습니다. 내가 읽고있는 파일은 여러 행으로되어 있습니다. 구분 기호로 사용되며, 아마도 첫 번째 연결된 목록의 끝에 도달하면 readFile 또는 insertNode에 아마도 오류가 발생합니다. 어떤 도움을 주시면 감사하겠습니다

blah division;first department;second department 

:

파일의 첫 번째 줄은 뭔가 같다. 내가 처리되지 않은 win32에서 예외에 StackOverflow의 검색의 처음 몇 페이지를 통해 검색, 그들은이 루프가 오류의 이유가 될 수

#define _CRT_SECURE_NO_WARNINGS 1 
#define FLUSH while (getchar() != '\n') 
#define DEFAULT "dept.txt" 
#define LENGTH 50 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 

//Structures 
typedef struct DEPT { 
char * DeptName; 
struct DEPT * link; 
} DEPT; 

typedef struct { 
char divisionName[LENGTH]; 
DEPT * first; 
} DIVISION; 

//Function Declarations 
int ReadFile (DIVISION DivArr [], int * lastDiv); 
FILE * getFileName (void); 
DEPT * insertNODE (DEPT * pList, char * string); 

int main (void) { 
//Local Declarations 
//Create the array of the DIVISION Structure 
DIVISION DivArr[20]; 
int i; 
int lastDiv; 
//Statements 
//Read in File 
if (ReadFile (DivArr, &lastDiv)) { 
    return 1; 
} 
for (i = 0; i < lastDiv; i++) { 
    printf ("%s\n",DivArr[i].divisionName); 
} 
return 0; 
} 
/*==================================ReadFile================================== 
Calls getFileName to get the file name to open, then reads the file's data into 
DivArr, parsing them appropriately, returning 1 if the file can't be opened */ 
int ReadFile (DIVISION DivArr [], int * lastDiv){ 
//Local Declarations 
FILE * datafile; 
char tempstring[300], *Ptoken; 
int linenum = 0; 
//Statements 
datafile = getFileName(); 

//return from function with 1 if file can't be opened 
//go through file line by line 
while (fgets(tempstring, sizeof(tempstring), datafile)) { 
    //tokenize string 
    Ptoken = strtok (tempstring , ";"); 
    //first part of string is assigned to divisionName 
    strncpy(DivArr[linenum].divisionName, Ptoken, LENGTH - 1); 
    DivArr[linenum].first = NULL; 

    //subsequent parts are assigned to linked list 
    while(Ptoken) { 
     Ptoken = strtok (NULL, ";\n"); 
     DivArr[linenum].first = insertNODE (DivArr[linenum].first, Ptoken); 
    } 
    linenum++; 
} 
*lastDiv = linenum; 
fclose(datafile); 
return 0; 
} //ReadFile 
/* =================================getFileName=============================== 
Gets input from the keyboard and if enter is pressed, returns default, otherwise        returns specified filename */ 
FILE * getFileName (void){ 
//local declarations 
int open = 1; 
char read[LENGTH]; 
FILE * datafile = NULL; 
//Statements 
//open file 
do{ 
    printf ("Enter a filename to open, or press enter for default:"); 
    fgets (read, LENGTH - 1, stdin); 
    if ('\n' == read[0]) { 
     strncpy (read , DEFAULT, LENGTH - 1); 
    } 
    else 
    read[strlen(read) - 1] = '\0'; 
    if((datafile = fopen(read, "r")) == NULL) 
     printf ("Error opening %s\n", read); 
    else 
     open = 0; 
} while (open == 1); 
return datafile; 
} //getFileName 
/* =================================insertNODE================================ 
Gets the address of the beginning of the list for the structure, then 
allocates memory for nodes, then allocates memory for string, then passes 
string to allocated memory, then links node 
*/ 
DEPT * insertNODE (DEPT * pList, char * string) 
{ 
//Local Declarations 
DEPT * pNew; 
DEPT * pWalker = pList; 
DEPT * pPre; 
//Statements 
if (!(pNew = (DEPT*)malloc(sizeof(DEPT)))) 
     printf ("\nMemory overflow in insert\n"), 
      exit (100); 
printf ("size of string + null = %d\n",strlen(string) + 1); 


    if(!(pNew->DeptName =(char*)calloc(strlen(string) + 1, sizeof(char)))) 
    { 
     printf ("\nMemory overflow in string creation\n"); 
     exit (100); 
    } 
    strncpy(pNew->DeptName, string, strlen(string)); 
    printf("%s is %d long", pNew->DeptName, strlen(pNew->DeptName)); 

if (pWalker == NULL) //first node in list 
{ 
    pNew->link = pList; 
    pList = pNew; 
} 
else { 
    while (pWalker){ 
     pPre = pWalker; 
     pWalker = pWalker->link; 
    } 
    pPre->link = pNew; 
    pNew->link = NULL; 
} 
return pList; 
} 
+0

"크래시"가 발생할 때 제일 먼저해야 할 일은 디버거에서 프로그램을 실행하는 것입니다. 충돌의 정확한 위치를 정확하게 파악할 수있을뿐만 아니라 변수가 원인인지 여부를 확인할 수 있습니다. –

+1

이 코드는 너무 복잡하여 .debug를 통과하여 실패한 일반적인 영역을 찾거나 문제를 재현 할 수있는 작은 컴파일 가능한 프로그램을 작성합니다. – Naveen

답변

1

위반 또는 메모리 오버 플로우 문제에 액세스 할 관련 같다 :

//subsequent parts are assigned to linked list 
while(Ptoken) { 
    Ptoken = strtok (NULL, ";\n"); 
    DivArr[linenum].first = insertNODE (DivArr[linenum].first, Ptoken); 
} 

strtokNULL을 반환하면 어떻게됩니까? 해당 에 대한 수표를strtokinsertNODE 사이에 추가하십시오.

+0

감사합니다. 그게 효과가 있었어. 나는 두 가지 사이의 if 문을 사용할 수 있었지만 루프보다 먼저 strtok을 호출하고 루프에서 함수를 먼저 호출 한 다음 strtok을 호출하는 것이 더 비쌉니다. 이렇게하면 while 루프가 모든 작업을 수행하고 함수 하나의 루프를 통해 저장됩니다. – lsiebert

+1

I/O를 수행하고 있기 때문에 현대 데스크톱 및 서버 CPU에서는 I/O가 처리를 완전히 왜소하게 만듭니다. 즉, 대부분의 시간 동안 디스크를 기다릴 필요가 없으므로 처리를 간소화하기 위해 매듭을 기울일 필요가 없습니다. – unwind

관련 문제