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后插入失败!
答案 0 :(得分:1)
可能导致分段错误的一个问题是在C ++程序中(错误地)使用malloc
和free
来动态创建对象。
这个结构:
struct node
{
string data;
struct node *next;
};
然后代码执行此操作:
nPtr = (nodePtr)malloc(sizeof(node));
不会创建node
个对象,因为未调用node
的构造函数,因此不会调用std::string
的默认构造函数。
所有malloc
都会分配sizeof(node)
个字节 - 实际上没有创建node
个对象。你现在留下了一堆分配的字节,它们不会形成任何类型的node
对象。使用nPtr
就像它是一个有效的对象一样,会调用未定义的行为。
而不是malloc
和free
,使用new
和delete
,因为new
会调用对象的构造函数,而malloc
则不会#39; t,除此之外,delete
会调用析构函数,free
则不会。
请使用以下内容替换您正在制作的malloc
和free
来电(当然,必要时更改变量的名称):
nPtr = new node;
然后完成时:
delete nPtr;
现在malloc
在创建对象时有用 - 它可用于placement-new之类的内容,您可以在其中发出对malloc
的调用,然后使用它来创建对象。但很明显,您的代码没有使用placement-new
。