为什么我在此功能中出现分段错误?

时间:2016-04-29 16:40:39

标签: c++ memory-management segmentation-fault g++ queue

我已经尝试了所有可能的方法。我认为函数findlink()中存在一些逻辑错误。该函数的目的是从参数abc中查找并返回一个模式。
例如,如果abc是“你好,我的名字是** Lorem ipsum坐下来,我是学生。”,然后findlink将返回“Lorem ipsum sit amet”。即它返回之间的文本双星号。但是由于某些原因我得到了分段错误,虽然我已经调试并发现故障仅涉及此功能,但我无法发现原因。

char *findlink(char *abc)
{
    if(abc==NULL)
        return NULL;
    cout<<"Findlink called for : "<<abc<<endl;
    int i=0,flag=0,flag1=0,len=0;
    char *link;
    for(i=0;i<strlen(abc)-1;i++)
    {
        if(abc[i]=='*' && abc[i+1]=='*' && flag==0)
        {
            flag=1;
            i+=2;
        }
        if(abc[i]=='*' && abc[i+1]=='*' && flag==1)
        {
            flag=0;
            flag1=1;
            i+=2;
        }
        if(flag==1 && flag1!=1)
            link[len++]=abc[i];
        if(flag1==1)
        {
            link[len++]='\0';
            cout<<"Returning "<<link<<endl;
            return link;
        }
    }
    cout<<"Returning NULL\n";
    return NULL;
}


以下是完整的参考代码。

#include<iostream>
#include<fstream>
#include<string.h>
#include<stdio.h>
using namespace std;
ifstream infile;
ofstream outfile;
struct queue
{
    struct node *front;
    struct node *rear;
};
struct queue* createqueue()
{
    struct queue *temp=new queue;
    temp->front=NULL;
    temp->rear=NULL;
    return temp;
}
struct node
{
    struct node *next;
    char *value;
};
struct node * createnode(char *val)
{
    struct node *new1=new node;
    new1->next=NULL;
    new1->value=val;
    return new1;
}
struct queue *push(char *val,struct queue *queue1)
{
    struct node *new1=createnode(val);
    if(queue1->front==NULL && queue1->rear==NULL)
    {
        queue1->front=queue1->rear=new node;
        queue1->rear=new1;
        queue1->front=new1;
    }
    else
    {
        queue1->rear->next=new node;
        queue1->rear->next=new1;
        queue1->rear=queue1->rear->next;
    }
    return queue1;
}
struct queue *push(string val,struct queue *queue1) //overloaded function push for string arguments
{
    char* cstr = new char[val.length() +1]; 
    strcpy(cstr, val.c_str()); 
    queue1=push(cstr,queue1);
    return queue1;
};
struct queue *pop(struct queue *queue1)
{
    struct node *temp=new node;
    if(queue1->front==NULL)
        return NULL;
    else if(queue1->front==queue1->rear)
    {
        temp=queue1->front;
        queue1->front=NULL;
        queue1->rear=NULL;
        cout<<"POP: Poping: "<<temp->value<<endl;
        return queue1;
    }
    else
    {
        temp=queue1->front;
        queue1->front=queue1->front->next;
        cout<<"POP: Poping: "<<temp->value<<endl;
        return queue1;
    }
}
struct queue *scanitall(struct queue *queue1)       //reads the contents from outputproject.txt and pushes all the contents in a queue
{
    string line;
    infile.open("outputproject.txt");
    while(getline(infile,line))
    {                    
        char *line1=new char[line.length()+1];
        strcpy(line1,line.c_str());
        queue1=push(line1,queue1);
    }
    infile.close();
    return queue1;
}
int search(struct queue* queue1,char *val)  //returns 1 if val found in queue1 else 0
{
    //cout<<"SEARCH called\n";
    if(queue1->front==NULL || queue1->rear==NULL)
        return 0;
    struct node *temp=new node;
    temp=queue1->front;
    while(temp)
    {
        if(strcmp(temp->value,val)==0)
            return 1;
        temp=temp->next;
    }
    return 0;
}
char *findlink(char *abc)
{
    if(abc==NULL)
        return NULL;
    cout<<"Findlink called for : "<<abc<<endl;
    int i=0,flag=0,flag1=0,len=0;
    char *link;
    for(i=0;i<strlen(abc)-1;i++)
    {
        if(abc[i]=='*' && abc[i+1]=='*' && flag==0)
        {
            flag=1;
            i+=2;
        }
        if(abc[i]=='*' && abc[i+1]=='*' && flag==1)
        {
            flag=0;
            flag1=1;
            i+=2;
        }
        if(flag==1 && flag1!=1)
            link[len++]=abc[i];
        if(flag1==1)
        {
            link[len++]='\0';
            cout<<"Returning "<<link<<endl;
            return link;
        }
    }
    cout<<"Returning NULL\n";
    return NULL;
}
struct queue *processit(struct queue *queue1,char *abc) //identifies link text in inputproject.txt
{
    //cout<<"PROCESSIT called\n";
    ofstream outfile;
    outfile.open("outputproject.txt",ios::app);
    if(!outfile)
        cout<<"PROCESSIT: Error file not opened!\n";
    char *link;
    link=findlink(abc);
    if(link)
        cout<<"Caught: "<<link<<endl;
    if(link)
        if(search(queue1,link)==0)
            {
                cout<<"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n";
                outfile<<link<<endl;
                queue1=push(link,queue1);
            }
    outfile.close();
    return queue1;
}
void openallfiles(struct queue *queue1)
{
    if(!queue1->rear)
        cout<<"Queue Empty\n";
    else
    {
        struct node *temp=new node;
        temp=queue1->front;
        string line;
        while(temp)
        {
            ifstream infile;
            infile.open(temp->value);
            if(!infile)
            {
                cout<<"openallfiles:File not opened\n";
                return;
            }
            while(getline(infile,line))
            {
                cout<<line<<endl;
            }
            infile.close();
            if(temp)
                temp=temp->next;
        }
    }
}/*
struct queue *findlinks(struct queue *crawl1,ifstream infile)
{

}
crawl(struct queue *crawl1)
{
    ifstream infile1,infile2;
    infile1.open("inputproject.txt");
    crawl1=findlinks(crawl1,infile1);
}*/
void display(struct queue *queue1)
{
    if(queue1->front)
    {
        struct node *temp=queue1->front;
        while(temp)
        {
            cout<<"data:"<<temp->value<<endl;
            temp=temp->next;
        }
    }
    else{
        cout<<"Sorry queue empty\n";
    }
}
int main()
{
    struct queue *queue1=createqueue();
    struct queue *crawl1=createqueue();
    queue1=scanitall(queue1);       //push all contents of outputproject.txt in  a queue
    display(queue1);
    //cout<<"Poping:\n";
    /*while(queue1->rear)
        queue1=pop(queue1);*/
    string line;
    char *line1;
    infile.open("inputproject.txt");
    while(getline(infile,line))
    {
        line1=new char[line.length()+1];
        strcpy(line1,line.c_str());
        queue1=processit(queue1,line1);
    }
    infile.close();
    openallfiles(queue1);
    return 0;
}

2 个答案:

答案 0 :(得分:2)

string类有一个构造函数,它接受以NULL结尾的C字符串。在您的情况下不使用strncpy()。要从C-String转换为string,您可以直接进行转换。例如:

char MyCharArray[] = "Whatever";

std::string MyStandardString(MyCharArray); // done

另一方面,要将string转换为C-String,您可以使用类string的内置函数,即应用D3规则< / em>:

char YourCharArray = YourString.c_str();

但这被认为是不好的做法,为什么?因为当你的字符串&#34;死了&#34;,所以你的char数组。

相反,你需要使用这样的东西:

std::string YourString = "hello world";
char* YourCharArray = new char[YourString.length() + 1]; // notice the "new", means your pointer "allocated" new memory just for itself

std::strcpy(YourCharArray, YourString.c_str());
delete[] YourCharArray; // this and only this will kill your CharArray. Which you "HAVE" to in order to "free" the memory once your program ends executing 

在此处查看C-String string上的Documentation stringC-String using namespace std; sudo npm uninstall -g ionic cordova bower

建议:不要练习使用npm cache clean 为什么?看这里:Here

答案 1 :(得分:0)

问题是struct node拥有指向char的指针。如果您追踪所有调用,则不会分配line1的副本,因此所有节点最终都指向同一个缓冲区。 (从技术上讲,它是未定义的行为,因为每次围绕line1循环while都不存在,但实际上,它们都指向堆栈上的相同位置。)

修复方法是让struct node按住std::string,然后调用strncpy,而不是调用click