程序收到信号SIGSEGV,分段故障.C ++清单 [英] Program received signal SIGSEGV, Segmentation fault. C++ LIST

查看:82
本文介绍了程序收到信号SIGSEGV,分段故障.C ++清单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果在 L.deleteElement()之后调用

L.insert()会给出分段错误.这是错误消息:

  196 nPtr =(nodePtr)malloc(sizeof(node));(gdb)打印(c)$ 7 = 2(gdb) 下一个第197回(gdb)打印(nPtr)$ 8 =(nodePtr)0x615c70(gdb)接下来198 nPtr-> data = element;(gdb)打印(元素)$ 9 =("(gdb)接下来程序收到信号SIGSEGV,分段故障.std :: __ cxx11 :: basic_string< char,std :: char_traits< char> ;, std :: allocator< char>中的0x00007ffff7b74413> :: _ M_assign(std :: __ cxx11 :: basic_string< char,std :: char_traits< char> ;, std :: allocator< char>> const&)()来自/usr/lib/x86_64-linux-gnu/libstdc++.so.6 

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

这是我的完整编排:

 #include< iostream>#include< stdlib.h>#include< string>使用命名空间std;结构节点{字符串数据;struct节点* next;};typedef结构节点node;typedef node * nodePtr;班级清单{nodePtr头;整数计数nodePtr尾部;上市:List(nodePtr h = NULL,int c = 0,nodePtr t = NULL){//构造函数头= h;count = c;tail = t;}布尔插入(string element,int position = 1);//如果position无效,则返回false;默认位置为开始"(1)bool deleteEle(int position);//删除指定位置的节点,否则返回false.};布尔List :: deleteEle(int position){if(position> count){返回false;}nodePtr pPtr;nodePtr cPtr;nodePtr tPtr;int p =位置;if(position == 1){cPtr = head;tPtr = cPtr-> next;头= tPtr;自由(cPtr);计数= = 1;返回true;}cPtr = head;pPtr = NULL;而(p> 1){pPtr = cPtr;cPtr = cPtr-> next;p--;}if(position == count){tail = pPtr;tail-> next = NULL;免费(cPtr);计数= = 1;返回true;}tPtr = cPtr-> next;pPtr-> next = tPtr;免费(cPtr);计数= = 1;返回true;}bool List :: insert(字符串元素,int位置){如果(position&count; count + 1){返回false;}int c =位置;nodePtr nPtr;nodePtr tPtr;nodePtr cPtr;nPtr =(nodePtr)malloc(sizeof(node));if(nPtr!= NULL){nPtr->数据=元素;nPtr-> next = NULL;tPtr = NULL;cPtr =头;if(cPtr == NULL){头= nPtr;tail = nPtr;count + = 1;返回true;}否则if(position == count + 1){cout<<"ikkade !!!";tail-> next = nPtr;tail = nPtr;count + = 1;返回true;}否则if(position == 1){头= nPtr;nPtr-> next = cPtr;count + = 1;返回true;}别的{while(cPtr!= NULL&& c> 2){cPtr = cPtr-> next;C - ;}tPtr = cPtr-> next;cPtr-> next = nPtr;nPtr-> next = tPtr;count + = 1;返回true;}}别的{cout<  

调用deleteEle后插入失败!

解决方案

一个可能导致分段错误的问题是在Microsoft中错误地使用了 malloc free 一个C ++程序来动态创建对象.

此结构:

  struct节点{字符串数据;struct节点* next;}; 

,然后再执行此操作的代码:

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

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

所有 malloc 所做的只是分配 sizeof(node)个字节-实际上没有创建 node 对象.现在,您剩下的只是一堆分配的字节,它们根本不构成任何类型的 node 对象.对 nPtr 的任何使用,就好像它是一个有效的对象一样,都会调用未定义的行为.

使用 new delete ,而不是 malloc free ,因为 new 会调用对象的构造函数,而 malloc 不会,并且 delete 会调用析构函数,而 free 不会.>

因此,用以下命令替换您现在正在执行的 malloc free 调用(当然,在必要时更改变量的名称):

nPtr =新节点;

然后完成:

删除nPtr;


现在 malloc 在创建对象时有其用途-可用于

I created a new node and didn't dereference any uninitialized pointer! Can anyone explain why I get this error? And it works as expected until I call it after L.deleteEle().

Here is my full prog:

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

Insert fails after calling deleteEle!

解决方案

One issue that can cause a segmentation fault is the (mis)use of malloc and free in a C++ program to create objects dynamically.

This struct:

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

and then later code doing this:

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

does not create node objects, since the constructor for node is not invoked, thus the default constructor for std::string is not invoked.

All the malloc does is allocate sizeof(node) bytes -- no node object is actually created. You are now left with a bunch of allocated bytes just laying around that do not form any sort of node object whatsoever. Any use of nPtr as if it is a valid object invokes undefined behavior.

Instead of malloc and free, use new and delete, since new calls the constructor for the object, while malloc doesn't, and in addtion, delete calls the destructor while free does not.

So replace the malloc and free calls you're making now with the following (of course, change the names of the variables where necessary):

nPtr = new node;

and then when done:

delete nPtr;


Now malloc has its uses when creating an object -- it can be used for things such as placement-new, where you would issue a call to malloc, and then use that to create the object. But obviously your code is not using placement-new.

这篇关于程序收到信号SIGSEGV,分段故障.C ++清单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆