高手请教,模拟指针链表插入一条记录数组越界或堆栈溢出?

weichaohnu 2009-04-04 05:27:41
模拟链表类simchain.h 和记录类TableRecor.h检查了所有功能都没有错
错误出在TableBody
TableBody的插入和追加一条记录的函数也是调用的simchain类的增加一个节点和追加一个节点的函数
调试的时候最后能实现插入一条记录和追加一条记录
输出也能输出
就是在按回车跳出调试的时候
用debug类型调试
跳出这么一个错误

Program:f:\课程实验\测试\simchain\Debug\simchain.exe
File:f\dd\vctools\crt_bld\self_x86\crt\dbgdel.cpp
Line:52

Expression:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)

For information on how your program can cause an assertion failure, see ......


用release类型调试的时候
跳出的错误显示是:
simchain.exe 中的 0x76ec59c3 处未处理的异常: 0xC0000005: 读取位置 0xe66426b4 时发生访问冲突


问题出在TableBody
网上查了好像说是数组越界
但是tablerecord类插入一个字段和追加一个字段一点问题都没有
只有在tablebody里插入一条记录和追加一条记录就出现这个问题....
调试了两天了,小弟实在找不出错误在哪
崩溃了!!
望高手给帮帮忙啊~~!!谢谢了啊
刚才那一贴忘了加分了
重发一个


//=========================
//simnode.h
//=========================

#include <iostream>
#include <string>
using namespace std;

template <class Elem>
class SimNode
{
public:
Elem m_data; //数据域
int m_link; //指向下一个节点
};


//==========================
//simspace.h
//==========================

#include "simnode.h"
#define DefaultSize 20

template<class Elem>
class SimSpace
{
private:
int m_NumOfNodes; //节点数量
int m_first; //指向可利用空间的第一个节点
SimNode<Elem> *m_node; //节点数组

public:
SimSpace(int MaxSpaceSize = DefaultSize);
~SimSpace() {delete [] m_node;}
SimNode<Elem> *NodeArry() const;
int &getFreeNode(); //返回可利用空间表的第一个节点
int Allocate(); //分配一个节点,返回数组下标
void Deallocate(int &i); //释放节点i
int getNumNodes() const;
};


template<class Elem>
SimSpace<Elem>::SimSpace( int MaxSpaceSize )
{
m_NumOfNodes = MaxSpaceSize;
m_node = new SimNode<Elem> [m_NumOfNodes];
for(int i=0;i<m_NumOfNodes-1;i++)
m_node[i].m_link = i+1;
m_node[m_NumOfNodes-1].m_link = -1;
m_first = 0;
}

template<class Elem>
SimNode<Elem> *SimSpace<Elem>::NodeArry() const
{
return m_node;
}

template<class Elem>
int &SimSpace<Elem>::getFreeNode()
{
return m_first;
}

template<class Elem>
int SimSpace<Elem>::Allocate()
{//分配一个自由节点
if(m_first == -1)
{
//扩容
}

int i = m_first;
m_first = m_node[i].m_link;
return i;
}

template<class Elem>
void SimSpace<Elem>::Deallocate(int &i)
{// 释放节点i,使i成为可利用空间表的第一个节点
m_node[i].m_link = m_first;
m_first = i;
i = -1;
}

template<class Elem>
int SimSpace<Elem>::getNumNodes() const
{
return m_NumOfNodes;
}


//========================
//simchain.h
//========================

#include "simspace.h"

template<class Elem>
class SimChain
{
public:
SimChain();
~SimChain(){}
void clear(); //使表为空
int length() const;
int search(const Elem &val);
bool getValue(Elem &item, int k) const; //获取第k个节点的值,赋给val
bool del(Elem &item, int k); //把第k个元素取至x,然后删除第k个节点
bool insert(const Elem &val,int k); //把val插入成为第k个节点
bool append(const Elem &val); //追加一个元素val
bool setValue(const Elem &val, int k); //改变或设置第k个节点数据
void print() const;
SimSpace<Elem> &simspace();

private:
int first; // 第一个节点的索引
SimSpace<Elem> m_simspace;
};

template<class Elem>
SimChain<Elem>::SimChain()
{
first = -1;
m_simspace.getFreeNode() = 1;
}

template<class Elem>
void SimChain<Elem>::clear()
{
int next;
while(first != -1)
{
next = m_simspace.NodeArry()[first].m_link;
m_simspace.Deallocate(first);
first = next;
}
}

template<class Elem>
bool SimChain<Elem>::insert(const Elem &val, int k)
{//把val插入成为第k个元素
if(k<1) return false;
int p = first;
for(int index=1;index<k-1 && p!=-1;index++)
p = m_simspace.NodeArry()[p].m_link; //使p指向第k-1个节点
if (k>1&&p == -1)
return false;
int y = m_simspace.Allocate();
m_simspace.NodeArry()[y].m_data = val;
if(k-1)
{ //在p之后插入
m_simspace.NodeArry()[y].m_link = m_simspace.NodeArry()[p].m_link;
m_simspace.NodeArry()[p].m_link = y;
}
else
{ // 作为链表首节点
m_simspace.NodeArry()[y].m_link = first;
first = y;
}
return true;
}

template<class Elem>
bool SimChain<Elem>::append(const Elem &val)
{
int y = m_simspace.Allocate();
m_simspace.NodeArry()[y].m_data = val;
int current = first;
int index=1;
if(current == -1)
{
first = y;
m_simspace.NodeArry()[y].m_link = -1;
return true;
}
while(current != -1)
{
index = current;
current = m_simspace.NodeArry()[current].m_link;
}
m_simspace.NodeArry()[index].m_link = y;
m_simspace.NodeArry()[y].m_link = -1;
return true;
}


template<class Elem>
void SimChain<Elem>::print() const
{
int current = first;
if(current == -1)
cout<<"表内无数据";
while(current != -1)
{
cout<<" "<<m_simspace.NodeArry()[current].m_data;
current = m_simspace.NodeArry()[current].m_link;
}
cout<<endl;
}

template<class Elem>
SimSpace<Elem> &SimChain<Elem>::simspace()
{
return m_simspace;
}

//========================
//TableRecord.h
//========================

#include "simchain.h"

class TableRecord
{
private:
SimChain<string> m_record; //数据成员为双向链表,记录字段信息

public:
TableRecord(void);
~TableRecord(void);
TableRecord(const TableRecord &item); //复制构造函数
int getRecordNum() const; //获取此条记录的字段数
void clear(); //删除头节点以外的所有节点
bool insert(const string &val,int pos); //插入成为第pos个节点
bool append(const string &val); //追加一个字段节点
bool remove(string &item,int pos); //删除第pos个字段节点
bool setValue(const string &val,int pos);//改变或设置第pos个字段的数据
bool getValue(string &item,int pos) const; //取得第pos个字段的数据信息
int searchValue(const string &val);//返回所查找字段的所在节点
void print();
friend ostream& operator<<(ostream &os,TableRecord &Tr);
friend istream& operator>>(istream &is,TableRecord &Tr);
};


//========================
//TableBody.h
//========================

#include "TableRecord.h"

class TableBody
{
private:
SimChain<TableRecord> m_DataRecord; //TableRecord类型的模拟链表

public:
TableBody(void){}
TableBody(const TableBody &val); //拷贝构造函数
~TableBody(void);
void clear(); //清空表体
int getRowSize() const; //获取记录数量
int getColSize(); //获取一条记录的字段数
bool appendRow(const TableRecord &rec); //追加一条记录
bool insertRow(const TableRecord &rec,int RowPos);//插入成为第RowPos条记录
bool removeRow(TableRecord &item, int RowPos); //删除第RowPos条记录

void print(); //输出表体
};

bool TableBody::appendRow(const TableRecord &rec)
{
return m_DataRecord.append(rec);
}

bool TableBody::insertRow(const TableRecord &rec,int RowPos)
{
return m_DataRecord.insert(rec,RowPos);
}


//=================================
//test.cpp
//=================================

#include "TableBody.h"

int main()
{
TableBody tb;
TableRecord tr1;
tr1.append("weichao");
tr1.append("20071610519");
tr1.append("boy");
tr1.insert("zhejiang",3);
tr1.append("shige");


/*tb.insertRow(tr1,1);*/
tb.appendRow(tr1);

tb.print();
system("pause");
}



...全文
318 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
lclhurricane 2010-12-31
  • 打赏
  • 举报
回复
我也遇到这个问题了
weichaohnu 2009-04-04
  • 打赏
  • 举报
回复
网速太慢,不知道分给出去没...
weichaohnu 2009-04-04
  • 打赏
  • 举报
回复
自己找到问题所在了,谢谢大家这么关注
在simspace类里还有一个析构函数我没发现
这个析构函数导致在内存释放的时候
tablerecord类和tablerecord类
分别delete了两次
出错了
哈哈 调试了两天终于找到问题所在了
太辛苦了
谢谢大家哈
分数就送给dizuo了
还是谢谢你这么帮忙!
sayoath 2009-04-04
  • 打赏
  • 举报
回复
我晕了。。也太长了。。

链表就是连出来的内存

定义个头。。每次操作时。。把头保存起来。。

删除时 先将指针指向下个地方。。再把当前的删掉。。

weichaohnu 2009-04-04
  • 打赏
  • 举报
回复
但是我所有类里面的析构函数都是空的...
在执行到退出的时候 它是如何delete的?
weichaohnu 2009-04-04
  • 打赏
  • 举报
回复
查了一下
还是csdn上说:
这是堆破坏所造成的,问题可能是在释放内存空间时对没有申请的空间进行释放   
或者已经被删除的空间进行删除时,就会出现这个错误。
weichaohnu 2009-04-04
  • 打赏
  • 举报
回复
以后表体还要和表头对应起来
我觉得用模拟链表
以后等表体表头对应起来之后
对表的列操作方便做索引
之前用过双向链表来保存一条记录
然后用容器来串联所有记录
但是最后 因为对容器不是很了解
没成功 就换做这种方式了
ryfdizuo 2009-04-04
  • 打赏
  • 举报
回复
估计和你的数据结构有关系,
你google一下: _block_type_is_valid phead- nblockuse
有些相关的问题帖子
PS: 我感觉为什么不用动态链表?
weichaohnu 2009-04-04
  • 打赏
  • 举报
回复
用的是vs2008
源代码在这里
simchain.rar
ryfdizuo 2009-04-04
  • 打赏
  • 举报
回复
不要贴了,
还得建这么多的头文件,代码倒是不多,麻烦,
打个包,
weichaohnu 2009-04-04
  • 打赏
  • 举报
回复
我精简一下代码



//========================
//simchain.h
//========================

#include "simspace.h"

template<class Elem>
class SimChain
{
public:
bool insert(const Elem &val,int k); //把val插入成为第k个节点
bool append(const Elem &val); //追加一个元素val
};

template<class Elem>
bool SimChain<Elem>::insert(const Elem &val, int k)
{//把val插入成为第k个元素
if(k<1) return false;
int p = first;
for(int index=1;index<k-1 && p!=-1;index++)
p = m_simspace.NodeArry()[p].m_link; //使p指向第k-1个节点
if (k>1&&p == -1)
return false;
int y = m_simspace.Allocate();
m_simspace.NodeArry()[y].m_data = val;
if(k-1)
{ //在p之后插入
m_simspace.NodeArry()[y].m_link = m_simspace.NodeArry()[p].m_link;
m_simspace.NodeArry()[p].m_link = y;
}
else
{ // 作为链表首节点
m_simspace.NodeArry()[y].m_link = first;
first = y;
}
return true;
}

template<class Elem>
bool SimChain<Elem>::append(const Elem &val)
{
int y = m_simspace.Allocate();
m_simspace.NodeArry()[y].m_data = val;
int current = first;
int index=1;
if(current == -1)
{
first = y;
m_simspace.NodeArry()[y].m_link = -1;
return true;
}
while(current != -1)
{
index = current;
current = m_simspace.NodeArry()[current].m_link;
}
m_simspace.NodeArry()[index].m_link = y;
m_simspace.NodeArry()[y].m_link = -1;
return true;
}

//========================
//TableRecord.h
//========================

#include "simchain.h"

class TableRecord
{
private:
SimChain<string> m_record; //数据成员为双向链表,记录字段信息

public:
void clear(); //删除头节点以外的所有节点
bool insert(const string &val,int pos); //插入成为第pos个节点
bool append(const string &val); //追加一个字段节点
bool remove(string &item,int pos); //删除第pos个字段节点
};

bool TableRecord::insert(const string &val,int pos)//插入成为第pos个节点
{return m_record.insert(val,pos);}

bool TableRecord::append(const string &val) //追加一个字段节点
{return m_record.append(val);}

//========================
//TableBody.h
//========================

#include "TableRecord.h"

class TableBody
{
private:
SimChain<TableRecord> m_DataRecord; //TableRecord类型的模拟链表

public:
bool appendRow(const TableRecord &rec); //追加一条记录
bool insertRow(const TableRecord &rec,int RowPos);//插入成为第RowPos条记录
};

bool TableBody::appendRow(const TableRecord &rec)
{ return m_DataRecord.append(rec);}

bool TableBody::insertRow(const TableRecord &rec,int RowPos)
{ return m_DataRecord.insert(rec,RowPos);}


//=================================
//test.cpp
//=================================

#include "TableBody.h"

int main()
{
TableBody tb;
TableRecord tr1;
tr1.append("weichao");
tr1.append("20071610519");
tr1.append("boy");
tr1.insert("zhejiang",3);
tr1.append("shige");


/*tb.insertRow(tr1,1);*/
tb.appendRow(tr1);

tb.print();
system("pause");
}
ryfdizuo 2009-04-04
  • 打赏
  • 举报
回复
你给出的程序不全啊,怎么帮你看?
打一个包。
weichaohnu 2009-04-04
  • 打赏
  • 举报
回复
在线等..........
无奈了,内存错误?
为什么是按回车跳出调试的时候出现这个中断错误
mylzc 2009-04-04
  • 打赏
  • 举报
回复
冒死帮楼主顶上去~!!!
mengde007 2009-04-04
  • 打赏
  • 举报
回复
楼主,太长了,最好精简点
Paradin 2009-04-04
  • 打赏
  • 举报
回复
好长。帮顶。

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧