如何定位指针错误?

时间:2017-05-12 00:16:05

标签: c++ pointers struct

我正在尝试创建一个程序来创建马尔可夫链但我有指针问题。当我运行程序时,我遇到了分段错误。

#include <stdio.h>
#include <cstring>
#include <cstdlib>
struct word;
struct nextword
{
    word* sourceword;
    word* next = 0;
};
int wordcount;
struct word
{
    char* wordstr;
    struct word* next = 0;
    nextword* followingword = 0;
    int nextwordcount = 0;
};
int main()
{
    word* firstword = 0;
    char * buffer = 0;
    long length;
    FILE * f = fopen ("alice.txt", "rb");

    if (f)
    {
        fseek (f, 0, SEEK_END);
        length = ftell (f);
        fseek (f, 0, SEEK_SET);
        buffer = (char *)malloc (length);
        if (buffer)
        {
            fread (buffer, 1, length, f);
        }
        fclose (f);
    }

    if (buffer)
    {
        char wordbuffer[500];
        int fileindex = 0;
        while(fileindex < length-1)
        {
            int wordindex = 0;
            while(buffer[fileindex] != ' ')
            {
                    wordbuffer[wordindex] = buffer[fileindex];
                    wordindex++;
                    fileindex++;
            }
            if(wordindex != 0)
                {
                    wordbuffer[wordindex] = '\0';
                    word* newword = (word*)malloc(sizeof(word));
                    char* newwordstr = (char*)malloc((strlen(wordbuffer)+1)*sizeof(char));
                    strcpy(newword->wordstr, newwordstr);
                    if(!firstword)
                {
                    firstword = newword;
                }
                    else
                {
                    word* testword = firstword;
                    while(!testword->next)
                        {
                            testword = (testword->next);
                        }
                    testword->next = newword;
                    printf(newword->wordstr);
                }
                }

            return 0;
        }
    }
    else
    {
            return 1;
    }

}

我试图删除文件读取部分并用硬编码字符串替换它,但问题仍然存在。

1 个答案:

答案 0 :(得分:0)

您可能想要了解STL并使用列表。或者使用C列表,参见几个例子, Adding node in front of linklist How to pop element from tail in linked list? Trying to make linkedlist in C

几个问题。修正了一些。编译。 我已经用你需要修复边界检查的地方注释了代码,而最大的问题可能是结构字的strcpy-&gt; wordstr uninitialized char *,

#include <stdio.h>
#include <cstring>
#include <cstdlib>
struct word;
struct nextword
{
    word* sourceword;
    word* next = 0;
};
int wordcount;
struct word
{
    char* wordstr; //what do you think this pointer points to?
    struct word* next = 0;
    nextword* followingword = 0;
    int nextwordcount = 0;
};
int main()
{
    FILE* fh = NULL;
    word* firstword = 0;
    char* buffer = 0;
    char* fname = "alice.txt";
    long length = 0; //you did not initialize length

    if ( (fh =  fopen ("alice.txt", "rb")) )
    {
        //why not use fstat to get file size?
        //why not use mmap to read file?
        fseek (fh, 0, SEEK_END);
        length = ftell (fh); //ok, length set here
        fseek (fh, 0, SEEK_SET);
        if( (buffer = (char *)malloc (length)) )
        {
            fread (buffer, 1, length, fh);
        }
        fclose (fh);
    }
    else
    {
        printf("error: cannot open %s",fname);
        exit(1);
    }
    printf("read %s, %ld\n",fname,length);

    if (!buffer)
    {
        printf("error: cannot open %s",fname);
        exit(1);
        //use exit, to return from main() //return 1;
    }

    //already checked buffer
    {
        int fileindex = 0;
        //put wordbuffer after fileindex, avoids stackoverflow overwrite
        char wordbuffer[500]; //500 bytes on stack, initialize?
        memset(wordbuffer,0,sizeof(wordbuffer));
        while(fileindex < length-1)
        {
            int wordindex = 0;
            //several errors in this line, check for null terminator,
            //check for newline, tab, basically any whitespace
            //while(buffer[fileindex] != ' ')
            while( buffer[fileindex] && buffer[fileindex] != ' ' )
            {
                wordbuffer[wordindex] = buffer[fileindex];
                wordindex++;
                fileindex++;
                //here is another error, do not overflow your stack based buffer
                if( wordindex>sizeof(buffer)-1 ) break; //do not overflow buffer
            }
            wordbuffer[wordindex] = '\0'; //terminate wordbuffer
            //since you chose wordindex signed, you want it > 0
            if(wordindex > 0)
            {
                //use a constructor
                word* newword = (word*)malloc(sizeof(word));
                //use a constructor
                //or just use strdup, since it is just a cstring
                char* newwordstr = strdup(wordbuffer);
                //no, just set pointer to the above allocated string
                //strcpy(newword->wordstr, newwordstr);
                newword->wordstr = newwordstr;
                if(!firstword)
                {
                    firstword = newword;
                }
                else
                {
                    word* testword = firstword;
                    while(!testword->next)
                    {
                        testword = (testword->next);
                    }
                    testword->next = newword;
                    printf(newword->wordstr);
                }
            }
            return 0;
        }
    }
    exit(0); //done
}

这样编译并运行没有错误,您需要查找链表处理。您应该实现一个链接列表,然后添加单词元素列表。