问题!问题? 问题!?
以下程序是用tc3。0编译通过,选择的模式为紧凑模式。
最先开始分配返回的地址,段地址和偏移地址都不为0,但是分配了一些了以后返回的地址都为0,这是为什么呢?!
//////////////////////////
//Header
//CCharList.h
class CCharListNode //In Heap....
{
public:
char cChar;
class CCharListNode far *pNext;
class CCharListNode far *pLast;
};
class CCharList
{
private:
CCharListNode far *pList;
CCharListNode far *pNodeOldLast;
unsigned int iNodeOldLast;
CCharListNode far* SeekNodeLast(unsigned int iPosition);
public:
unsigned int iListLength;
CCharList(void);
~CCharList(void);
int CreateList(void);
int InsertNode(char cChar, unsigned int iPosition);
int DeleteNode(unsigned int iPosition);
int DeleteList(void);
int GetCharFromNode(char &cChar, unsigned int iPosition);
int SetCharToNode(char cChar, unsigned int iPosition);
};
////////////////////
//cpp file
//CCharList.cpp
#include <stdio.h>
#include <alloc.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#define Min(x, y) x<y ? x:y
#include "CCharList.h"
CCharList::CCharList(void)
{
CreateList();
}
int CCharList::CreateList(void)
{
pList=(CCharListNode far*) farmalloc(sizeof(CCharListNode)); // if(!pList)
return 0;
printf("[%x:%x] ", FP_SEG(pList), FP_OFF(pList));
iListLength=0;
pList->pNext=pList;
pList->pLast=pList;
pNodeOldLast=pList;
iNodeOldLast=0;
return 1;
}
int CCharList::InsertNode(char cChar, unsigned int iPosition)
{
if(iPosition>iListLength+1 || iPosition<1) return 0;
CCharListNode far *pNode=(CCharListNode far*)
farmalloc(sizeof(CCharListNode));//if(!pNode) return 0;
CCharListNode far *pSeek=this->SeekNodeLast(iPosition);
printf(" [%x:%x] ", FP_SEG(pNode), FP_OFF(pNode));
pNode->pNext=pSeek->pNext;
pSeek->pNext=pNode;
pNode->pLast=pSeek;
pNode->pNext->pLast=pNode;
pNode->cChar=cChar;
iListLength++;
return 1;
}
int CCharList::DeleteNode(unsigned int iPosition)
{
if(iPosition>iListLength || iPosition<1) return 0;
CCharListNode far *pNode;
CCharListNode far *pSeek=this->SeekNodeLast(iPosition);
pNode=pSeek->pNext;
pSeek->pNext=pNode->pNext;
pNode->pNext->pLast=pSeek;
farfree(pNode);
iListLength--;
return 1;
}
int CCharList::GetCharFromNode(char &cChar, unsigned int iPosition)
{
if(iPosition>iListLength || iPosition<1) return 0;
CCharListNode far *pSeek=this->SeekNodeLast(iPosition);
cChar=pSeek->pNext->cChar;
return 1;
}
int CCharList::SetCharToNode(char cChar, unsigned int iPosition)
{
if(iPosition>iListLength || iPosition<1) return 0;
CCharListNode far *pSeek=this->SeekNodeLast(iPosition);
pSeek->pNext->cChar=cChar;
return 1;
}
int CCharList::DeleteList(void)
{
int iLimit=iListLength;
for(unsigned int i=0; i<iLimit; i++)
this->DeleteNode(1);
farfree(pList);
return 1;
}
CCharList::~CCharList(void)
{
DeleteList();
}
CCharListNode far* CCharList::SeekNodeLast(unsigned int iPosition)
{
iPosition--;
CCharListNode far *pSeek;
unsigned int iDistanceFromHead;
unsigned int iDistanceFromOldLast;
unsigned int iDistanceTemp;
unsigned int iDistance;
iDistanceFromHead=Min(iListLength+1-iPosition, iPosition);
iDistanceTemp=iNodeOldLast<iPosition ?
iPosition-iNodeOldLast:iNodeOldLast-iPosition;
iDistanceFromOldLast=Min(iListLength+1-iDistanceTemp, iDistanceTemp);
iDistance=Min(iDistanceFromHead, iDistanceFromOldLast);
unsigned int i;
if(iDistance==iDistanceFromHead)
{
pSeek=pList;
if(iDistance==iPosition)
{
for(i=0; i<iDistance; i++)
pSeek=pSeek->pNext;
}
else
{
for(i=0; i<iDistance; i++)
pSeek=pSeek->pLast;
}
}
else
{
pSeek=pNodeOldLast;
if(iNodeOldLast<iPosition)
{
for(i=0; i<iDistance; i++)
pSeek=pSeek->pNext;
}
else
{
for(i=0; i<iDistance; i++)
pSeek=pSeek->pLast;
}
}
iNodeOldLast=iPosition;
pNodeOldLast=pSeek;
return pSeek;
}
/////////////////////
//the main file
//main.cpp
#include <stdio.h>
#include <conio.h>
#include "CCharList.h"
//int ShowString(CString str);
int main()
{
clrscr();
gotoxy(1, 1);
CCharList oCharList;
for(long int i=0; i<4000000; i++)
{
oCharList.InsertNode('1', 1);
if(i%10000==0 && i!=0)
{
printf("\n==%d==\n", i);
getch();
}
}
printf("\nEnd Here!");
getch();
return 1;
}
问题点数:100、回复次数:23Top
1 楼chang_bo(夜鹰 MS MVP http://blog.sina.com.cn/changbo)回复于 2002-04-11 17:54:27 得分 0
upTop
2 楼lbsxyk(殷商的鬼)回复于 2002-04-11 19:30:06 得分 0
只能帮你UP一下Top
3 楼bysysnet(问自己)回复于 2002-04-11 19:32:08 得分 0
太长,等我copy后慢慢研究。
上@!!!Top
4 楼zhenhao(轻松XP)回复于 2002-04-14 19:49:12 得分 0
不是操作系统的问题吧。程序太长了。Top
5 楼kiss_lon(瞌睡龙)回复于 2002-04-15 00:41:28 得分 0
你是高手,UPTop
6 楼mrzho(mrzhou)回复于 2002-05-15 14:30:04 得分 0
你所选的模式只能在64K里操作,对内存的管理有限,有可能是你分配的内存大于64K所以出错了。Top
7 楼lijiuhua0721(随缘)回复于 2002-05-16 06:54:35 得分 0
upTop
8 楼MagicianZ(MagicianX)回复于 2002-05-18 12:16:26 得分 0
你是在实现树型数据结构吧?用紧凑模式编译时好像不能使用远指针,所以当你分配一定数目的内存后,指针就会从近程堆里跑掉,(TC3 本身会自动把他转成远指针),但是对于程序来说,还是只认指针变量中相当与近指针的那个部分,所以看上去都是零。 我个人还有一个推测(时间紧,没法试了),如果继续分配内存的话,很快会死机.(因为访问非法内存区,系统保护性挂起)。Top
9 楼lijiuhua0721(随缘)回复于 2002-05-18 15:12:47 得分 0
upTop
10 楼wgjmail(笑面佛)回复于 2002-05-18 15:17:27 得分 0
upTop
11 楼ckc(火)回复于 2002-05-19 20:51:04 得分 0
TC 3.0只能使用基本内存640K,算上系统开销,能有600K就非常好了。
你需要的内存太大了,无法满足。
这种程序还是拿到windows下做吧。DOS下做需要自己管理内存,很麻烦的。
另外,watcom c++在dos下就可以直接使用640K以上的内存,不过好象很少人用那个东西。Top
12 楼sunxking(sunx)回复于 2002-05-19 21:14:46 得分 0
哈哈,同意ckc(ckc)
这个问题就是因为内存不够造成的了。
dos程序员,只能使用640K的内存,如果被其他程序占据掉的话,那就更少了,所以必须使用扩展内存,himem.sys和emm386.exe可以用来管理扩展内存,具体方法是调用几个中断。这里就不多说了。
建议在Vc6.0或C++Buileder下调试,那样的话就不用自己管理扩展内存了!
Top
13 楼hquwl(东北大汉)回复于 2002-05-20 15:16:15 得分 0
Copy先。Top
14 楼MagicianZ(MagicianX)回复于 2002-05-21 10:31:26 得分 0
TC 3.0 的紧凑模式只能使用64K大的近程堆,要是能用 640K 的话这个程序就应该没问题了。Top
15 楼MagicianZ(MagicianX)回复于 2002-05-21 10:32:52 得分 0
我个人建议使用 WATCOM C++10.00 编译试试。Top
16 楼993305(DaYan)回复于 2002-05-21 19:06:28 得分 0
同意 sunxking(sunx的意见,在 vc或c++bulider下调试Top
17 楼wgjmail(笑面佛)回复于 2002-05-21 20:58:51 得分 0
太长了吧,看睡着了Top
18 楼boyfling(GGS)回复于 2002-06-01 21:43:01 得分 0
疑问:
如何调用几个中断来管理扩展内存呢?!!!Top
19 楼rosson(新星罗雄)回复于 2002-06-06 18:43:31 得分 0
太长了吧,看睡着了Top
20 楼carfieldQ_Q(加菲)回复于 2002-06-07 11:46:37 得分 0
4000000 太大了吧!
就算能分配(虚拟内存技术早已突破了dos的640k局限,换句话说:dos下绝对可以使用大于640k的空间),运算起来的时候所用空间会成倍增加(你所用的那些系统调用比如函数等都是要用空间的)。
而且结点数过多,会使程序过分复杂,所以失败的原因除了内存问题还有可能是程序自身的死锁。把数目逐渐减小试试。或者用单步调试,看看什么时候程序会失控,)
另外famalloc不能再紧凑模式下用,顺便说一句编译模式,如果你使用的是pc的话最好不要改,用默认的就行了
Top
21 楼wgjmail(笑面佛)回复于 2002-06-15 23:40:08 得分 0
太长了吧,看着老累睡着了Top
22 楼daehappy(追求120%结贴)回复于 2002-06-20 20:29:54 得分 0
up!gz!Top
23 楼sunxking(sunx)回复于 2002-06-23 11:16:22 得分 100
前几天考试去了,没想到还在讨论啊,我给你一个管理扩展内存具体一点的方法把:
主要的两个中断:
中断2FH,功能43H,子功能00H,安装效验,用来确定XMS管理扩展内存的软件是否存在,返回AL=80H的话,正常安装,不等的话,就说明无驱动程序,给ni个例子
如:
int check()
{
_AX=0x4300;
feninterrupt(0x2f);
if (_AH!=80) {cout<<"himem.sys not found";return 0;}
return 1;
}
中断1FH,功能43H,子功能10H,取得XMS驱动程序地址:
返回,ES:BX为驱动程序的入口点(以后每次要进行XMS功能调用都要从此入口点进入!)。
void far (*XMSHandl)();
void GetXMSHandle;
{
_AX=0x4310;
feninterrupt(0x2f);
XMSHandle=(void far(*)())MK_FP(_ES,_BX);
}
几个比较重要的XMS功能调用:
1.询问扩展内存
ah=08h
返回:AX=按k计算的最大扩展内存的大小,BL=错误代码,
DX=按k计算的总扩展内存的大小
2.分配扩展内存
ah=09h,dx=所需k字节
返回:AX=0001H则成功,AX=0000H则失败,BL=错误代码,
DX=内存块句柄
3.移动扩展内存块
ah=0bh,ds:si指向EMM结构。
返回:ax=0001h成功,0000h失败,bl=错误代码
4.释放扩展内存:
ah=0ah,dx=要释放的句柄
返回:ax=0001h成功,0000h失败,bl=错误代码
XMS功能调用,举个例子:
unsigned int XMSmalloc(unsigned sizek)
{
_AH=8;
XMSHandle(); //就是上面例子里的那个XMSHandle了
if (_AX<sizek) {cout<<"not enough memory";return 0;}
_DX=sizek;_AH=9;
XMSHandle();
if (_AX<sizek) {cout"XMS malloc Error!";return 0;}
return _DX;
}
只要有了上面几个中断,就基本可以任意控制扩展内存了。
你写程序因该是足够用了。Top




