【问题标题】:C programming, causing unhandled win32 exception, possibly in strlen function.C 编程,导致未处理的 win32 异常,可能在 strlen 函数中。
【发布时间】:2012-04-16 06:15:29
【问题描述】:

我在 visual-studio 2010 中编写的 c 程序抛出未处理的 win32 异常。

我认为它在 strlen 函数中,基于调试器输出,但我不确定。 我正在阅读的文件是多行,带有 ;用作分隔符,当我到达第一个链表的末尾时,错误似乎发生了,所以大概在 readFile 或 insertNode 中。

文件的第一行是这样的:

blah division;first department;second department

任何帮助将不胜感激。我在 StackOverflow 搜索的前几页中搜索了未处理的 win32 异常,它们似乎与访问冲突或内存溢出问题有关

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

【问题讨论】:

  • 当您遇到“崩溃”时,您应该做的第一件事是在调试器中运行您的程序。它将帮助您查明崩溃的确切位置,并让您检查变量以查看可能导致崩溃的原因。
  • 这只是太多代码,无法通过..调试并找到它失败的一般区域,或者编写一个可以重现问题的小型可编译程序。

标签: c visual-studio-2010 unhandled-exception


【解决方案1】:

这个循环可能是你的错误的原因:

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

strtok 返回NULL 时会发生什么?在strtokinsertNODE 之间添加一个检查

【讨论】:

  • 谢谢!那行得通。我可以在两者之间使用 if 语句(我首先尝试过,并且成功了),但这比在循环之前调用 strtok 一次,并在循环中首先调用函数,然后是 strtok 更昂贵。这样一来,while 循环就可以完成所有工作,并节省了通过函数的一个循环。
  • 由于这是在执行 I/O,因此在现代桌面和服务器 CPU:s 上,I/O 很可能会使处理完全相形见绌。换句话说,您不需要将自己扭成一个结来简化处理,因为无论如何它大部分时间都会坐在那里等待磁盘。
猜你喜欢
  • 2012-05-18
  • 2011-01-29
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多