程序接收信号SIGSEGV,分段故障。 C ++列表

时间:2018-01-31 14:12:56

标签: c++ linked-list segmentation-fault

如果我在 L.deleteElement()之后调用它,则

L.insert()会出现细分错误。 这是错误消息:

196     nPtr = (nodePtr)malloc(sizeof(node));
(gdb) print(c)
$7 = 2
(gdb) next
197     if(nPtr!=NULL){
(gdb) print(nPtr)
$8 = (nodePtr) 0x615c70
(gdb) next
198         nPtr->data = element;
(gdb) print(element)
$9 = "("
(gdb) next

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b74413 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6

我创建了一个新节点,并没有取消引用任何未初始化的指针!谁能解释为什么我会收到这个错误?并且它按预期工作,直到我在L.deleteEle()之后调用它。

这是我的完整编程:

#include<iostream>
#include<stdlib.h>
#include<string>
using namespace std;
struct node
{
    string data;
    struct node *next;
};
typedef struct node node;
typedef node* nodePtr;
class List
{
    nodePtr head;
    int count;
    nodePtr tail;
public:
    List(nodePtr h=NULL,int c=0,nodePtr t=NULL){ // constructor
        head=h;
        count=c;
        tail=t;
    } 
    bool insert(string element, int position=1); // if position is invalid, returns false ; takes default position as START (1)
    bool deleteEle(int position); // deletes the node at specified position, else returns false.
};

bool List::deleteEle(int position)
{
    if(position>count){
        return false;
    }
    nodePtr pPtr;
    nodePtr cPtr;
    nodePtr tPtr;
    int p=position;
    if(position==1){
        cPtr=head;
        tPtr=cPtr->next;
        head=tPtr;
        free(cPtr);
        count-=1;
        return true;
    }
    cPtr=head;
    pPtr=NULL;
    while(p>1){
        pPtr=cPtr;
        cPtr=cPtr->next;
        p--;
    }
    if(position==count){
        tail=pPtr;
        tail->next=NULL;
        free(cPtr);
        count-=1;
        return true;
    }
    tPtr=cPtr->next;
    pPtr->next=tPtr;
    free(cPtr);
    count-=1;
    return true;
}
bool List::insert(string element, int position)
{
    if (position>count+1){
        return false;
    }
    int c = position;
    nodePtr nPtr;
    nodePtr tPtr;
    nodePtr cPtr;
    nPtr = (nodePtr)malloc(sizeof(node));
    if(nPtr!=NULL){
        nPtr->data = element;
        nPtr->next = NULL;

        tPtr = NULL;
        cPtr = head;
        if(cPtr==NULL){
            head=nPtr;
            tail=nPtr;
            count+=1;
            return true;
        }
        else if(position==count+1){
            cout<<"ikkade !!!";
            tail->next=nPtr;
            tail=nPtr;
            count+=1;
            return true;
        }
        else if(position==1){
            head=nPtr;
            nPtr->next=cPtr;
            count+=1;
            return true;
        }
        else{
            while(cPtr!=NULL && c>2){
                cPtr = cPtr->next;
                c--; 
            }
            tPtr=cPtr->next;
            cPtr->next=nPtr;
            nPtr->next=tPtr;
            count+=1;
            return true;
        }
    }
    else{
        cout<<element<<" not inserted! No memory available.";
        return false;
    }
}
int main(void)
{
    List L;
    L.insert("(",L.size()+1);
    L.insert("+",L.size()+1);
    L.deleteEle(L.size());
    L.insert("(",L.size()+1); //fails here
return 0;       
}
调用deleteEle后

插入失败!

1 个答案:

答案 0 :(得分:1)

可能导致分段错误的一个问题是在C ++程序中(错误地)使用mallocfree来动态创建对象。

这个结构:

struct node
{
    string data;
    struct node *next;
};

然后代码执行此操作:

nPtr = (nodePtr)malloc(sizeof(node));

不会创建node个对象,因为未调用node的构造函数,因此不会调用std::string的默认构造函数。

所有malloc都会分配sizeof(node)个字节 - 实际上没有创建node个对象。你现在留下了一堆分配的字节,它们不会形成任何类型的node对象。使用nPtr就像它是一个有效的对象一样,会调用未定义的行为。

而不是mallocfree,使用newdelete,因为new会调用对象的构造函数,而malloc则不会#39; t,除此之外,delete会调用析构函数,free则不会。

请使用以下内容替换您正在制作的mallocfree来电(当然,必要时更改变量的名称):

nPtr = new node;

然后完成时:

delete nPtr;

现在malloc在创建对象时有用 - 它可用于placement-new之类的内容,您可以在其中发出对malloc的调用,然后使用它来创建对象。但很明显,您的代码没有使用placement-new