考虑以下代码: 使用visual studio运行时,调试器在testLevel_0类中输入test_create函数时会卡住。我相信这与磁盘结构的初始化有关,我无法找到问题。出于某种原因,永远不会调用Disk的构造函数。如果在任何其他功能中声明了磁盘,则会出现类似的问题。
using namespace std;
typedef bitset<1600> DATtype;
bool charToBool(char ch)
{
return ch != '0';
}
string getDateNow()
{
char temp[10];
int a;
string ret;
time_t now;
struct tm *current;
now = time(0);
current = localtime(&now);
ret = ((current->tm_mday < 10)? '0'+current->tm_mday:current->tm_mday);
ret += ":" ;
ret += ((current->tm_mon < 10)? '0'+current->tm_mon:current->tm_mon);
ret += ":";
ret += _itoa(current->tm_year+1900,temp,10);
return ret;
}
struct VHD
{
char diskName[12]; // disk name
char diskOwner[12]; // disk owner name
char probDate[10]; // creation date
unsigned int clusQty; // cluster total on disk
unsigned int dataClusQty; // number of allocational units for data
unsigned int addrDAT; // DAT sector address
unsigned int addrRootDir; // root cluster address
unsigned int addrDATcpy; // DAT copy sector address
unsigned int addrRootDirCpy; // root copy cluster address
unsigned int addrDataStart; // address of first cluster meant for data
char formatDate[10]; // format date
bool isFormatted; // is formatted
char emptyArea[947]; // saved memory for future use
VHD()
{
strcpy(diskName,"name");
strcpy(diskOwner,"owner");
strcpy(probDate,"00/00/000");
clusQty = dataClusQty = addrDAT = addrRootDir = addrDATcpy = addrRootDirCpy = addrDataStart = 0;
strcpy(formatDate,"00/00/0000");
isFormatted = false;
strcpy(emptyArea,"000000000");
}
VHD(VHD& copy)
{
strcpy(diskName , copy.diskName);
strcpy(diskOwner , copy.diskOwner);
strcpy(probDate , copy.probDate);
clusQty = copy.clusQty;
dataClusQty = copy.dataClusQty;
addrDAT = copy.addrDAT;
addrRootDir = copy.addrRootDir;
addrDATcpy = copy.addrDATcpy;
addrRootDirCpy = copy.addrRootDirCpy;
addrDataStart = copy.addrDataStart;
strcpy(formatDate , copy.formatDate);
isFormatted = copy.isFormatted;
strcpy(emptyArea , copy.emptyArea);
}
const const char * toData()
{
string ret = diskName;
ret += diskOwner;
ret += probDate;
ret += (char *)clusQty;
ret += (char *)dataClusQty;
ret += (char *)addrDAT;
ret += (char *)addrRootDir;
ret += (char *)addrDATcpy;
ret += (char *)addrRootDirCpy;
ret += (char *)addrDataStart;
ret += formatDate;
ret += (char) isFormatted;
ret += emptyArea;
return ret.c_str();
}
};
struct DAT
{
unsigned int sectrNr;
DATtype dat;
char emptyArea[816];
DAT()
{
sectrNr = 0;
strcpy(emptyArea,"0000000000000");
}
const char * toData()
{
string ret = dat.to_string();
ret += emptyArea;
return ret.c_str();
}
};
struct dirEntry
{
char fileName [12]; // name of file
char fileOwner[12]; // owner of file
unsigned int fileAddr; // address of first sector of file
char crDate[10]; // date of file creation
unsigned int fileSize; // size of file, number of sectors
unsigned int eofRecNr; // "end of file" location
unsigned int maxRecSize; // max record size
unsigned int actualRecSize; // actual record size
char recFormat[2]; // record format: 'F','V' - data; 'D' - sub-directory
unsigned int keyOffset; // offset of key within record
unsigned int keySize; // size of key
char keyType[2]; // type of key: 'I' - int, 'F' - float, 'D' - double, 'C' - char/string
unsigned char entryStatus;// status of file entry: 0 - entry is empty, 1 - entry is active, 2 - entry is not active
dirEntry()
{
strcpy(fileName,"name");
strcpy(fileOwner,"owner");
strcpy(crDate,"00/00/0000");
fileAddr = fileSize = eofRecNr = maxRecSize = actualRecSize = keyOffset = keySize = 0;
strcpy(recFormat,"00");
strcpy(keyType,"00");
entryStatus = '0';
}
const char * toData()
{
string ret = fileName;
ret += fileOwner;
ret += (char *)fileAddr;
ret += crDate;
ret += (char *)fileSize;
ret += (char *)eofRecNr;
ret += (char *)maxRecSize;
ret += (char *)actualRecSize;
ret += recFormat;
ret += (char *)keyOffset;
ret += (char *)keySize;
ret += keyType;
ret += entryStatus;
return ret.c_str();
}
};
struct rootDirSec
{
unsigned int sectorNr;
dirEntry rootdir[14];
char emptyArea[12];
rootDirSec()
{
sectorNr = 0;
strcpy(emptyArea,"00000");
}
const char * toData()
{
string ret;
for(int i=0;i<18;i++)
ret += rootdir[i].toData();
return ret.c_str();
}
};
struct rootDirectory
{
rootDirSec rootDirs[2];
const char * toData()
{
string ret;
for(int i=0;i<2;i++)
ret += rootDirs[i].toData();
return ret.c_str();
}
};
struct fileHeader
{
unsigned int sectorNr; // sector number
dirEntry fileDesc; // file descriptor
DATtype fat; // file access table
char emptyArea[744];
fileHeader()
{
sectorNr = 0;
strcpy(emptyArea,"0000000");
}
const char * toData()
{
string ret = fileDesc.toData();
ret += fat.to_string();
ret += emptyArea;
return ret.c_str();
}
};
struct sector
{
unsigned int sectorNr; // sector number
char rawData[1020]; // data
sector()
{
sectorNr = 0;
strcpy(rawData,"000000000");
}
const char * toData()
{
return rawData;
}
};
struct cluster
{
sector sectors[2];
const char * toData()
{
string ret = sectors[0].toData();
ret += sectors[1].toData();
return ret.c_str();
}
};
struct Disk
{
cluster clusters[1600];
friend class TestLevel_0;
VHD vhd;// cluster 0 sector 0
DAT dat;// cluster 0 sector 1
//rootDirectory rootDir; // clusters 1 - 1599
bool mounted; // if disk is mounted - true
fstream dskfl;
unsigned int currDiskSectorNr; // indexer
Disk()
{
mounted = false; // all other fields are automatically initialized when Disk is declared
}
Disk(string & name, string & owner, char code, unsigned int a = 0)
{
mounted = false;
switch(code)
{
case 'c':
createdisk(name,owner);
case 'm':
mountdisk(name);
break;
}
}
~Disk()
{
unmountdisk();
}
void strToVHD(string str)
{
string temp[10];
int pos = 0;
if(str.length() != 1)
return;
strcpy(vhd.diskName,str.substr(pos,12).c_str()); pos +=12;
strcpy(vhd.diskOwner,str.substr(pos,12).c_str()); pos += 12;
strcpy(vhd.probDate,str.substr(pos,10).c_str()); pos += 10;
vhd.clusQty = atoi(str.substr(pos,sizeof(int)).c_str()); pos += sizeof(int);
vhd.dataClusQty = atoi(str.substr(pos,sizeof(int)).c_str()); pos += sizeof(int);
vhd.addrDAT = atoi(str.substr(pos,sizeof(int)).c_str()); pos += sizeof(int);
vhd.addrRootDir = atoi(str.substr(pos,sizeof(int)).c_str()); pos += sizeof(int);
vhd.addrDATcpy = atoi(str.substr(pos,sizeof(int)).c_str()); pos += sizeof(int);
vhd.addrRootDirCpy = atoi(str.substr(pos,sizeof(int)).c_str()); pos += sizeof(int);
vhd.addrDataStart = atoi(str.substr(pos,sizeof(int)).c_str()); pos += sizeof(int);
strcpy(vhd.formatDate,str.substr(pos,10).c_str()); pos += 10;
vhd.isFormatted = charToBool(str.at(pos++));
strcpy(vhd.emptyArea,str.substr(pos,947).c_str());
}
string VHDTostr()
{
char temp[10];
string str = vhd.diskName;
str += vhd.diskOwner;
str += vhd.probDate;
str += _itoa(vhd.clusQty,temp,10);
str += _itoa(vhd.dataClusQty,temp,10);
str += _itoa(vhd.addrDAT,temp,10);
str += _itoa(vhd.addrRootDir,temp,10);
str += _itoa(vhd.addrDATcpy,temp,10);
str += _itoa(vhd.addrRootDirCpy,temp,10);
str += _itoa(vhd.addrDataStart,temp,10);
str += vhd.formatDate;
str += (vhd.isFormatted?'1':'0');
str += vhd.emptyArea;
return str;
}
void createdisk(string & name, string & owner)
{
dskfl.open(name,ios::binary);
for(int i=0,k=0,j=0;i<2;i++,k=1)
for(;j<1600;j++,k+=2)
clusters[j].sectors[i].sectorNr = k;
strcpy(vhd.diskName,name.c_str());
strcpy(vhd.diskOwner,owner.c_str());
time_t now = time(0);
strcpy(vhd.formatDate,getDateNow().c_str());
vhd.clusQty = 1600;
vhd.dataClusQty = 1596;
vhd.addrDAT = 1;
vhd.addrRootDir = 1;
vhd.addrDataStart = 2;
vhd.addrDATcpy = 1599;
vhd.addrRootDirCpy = 800;
vhd.isFormatted = false;
strcpy(clusters[0].sectors[0].rawData,vhd.toData());
char temp[10];
for(int i=0,j;i<1600;i++)
{
for(j=0;j<2;j++)
{
dskfl.write(_itoa(clusters[i].sectors[j].sectorNr,temp,10),sizeof(int));
dskfl.write(clusters[i].sectors[j].rawData,sizeof(char[1020]));
}
}
}
void mountdisk(string & file)
{
char * str = new char;
dskfl.open(file ,ios::binary);
dskfl.get(str,sizeof(int));
clusters[0].sectors[0].sectorNr = (int)str;
dskfl.get(str,sizeof(char[1020]));
strcpy(clusters[0].sectors[0].rawData,str);
strToVHD(str);
mounted = true;
}
void unmountdisk()
{
string str = VHDTostr();
strcpy(clusters[0].sectors[0].rawData , str.c_str());
dskfl.close();
mounted = false;
}
void recreatedisk(string & name)
{
dskfl.open(name , ios::binary);
if(!dskfl.is_open() || mounted)
return;
VHD newVhd;
strcpy(newVhd.diskName,name.c_str());
strcpy(newVhd.diskOwner,vhd.diskOwner);
time_t now = time(0);
strcpy(newVhd.formatDate,getDateNow().c_str());
newVhd.clusQty = 1600;
newVhd.addrDAT = 1;
newVhd.addrRootDir = 2;
newVhd.isFormatted = false;
vhd = newVhd;
strcpy(clusters[0].sectors[0].rawData,vhd.toData());
char temp[10];
for(int i=0,j;i<1600;i++)
{
for(j=0;j<2;j++)
{
dskfl.write(_itoa(clusters[i].sectors[j].sectorNr,temp,10),sizeof(int));
dskfl.write(clusters[i].sectors[j].rawData,sizeof(char[1020]));
}
}
}
fstream * getdskfl()
{
if(dskfl.is_open())
return &dskfl;
return 0x0;
}
void seekToSector(unsigned int index)
{
if(index <= 0 || index >= 1600)
throw;
currDiskSectorNr = index;
}
void writeSector(unsigned int index, sector * sec)
{
try
{
seekToSector(index);
}
catch(exception ex)
{
throw "Error index input";
}
writeSector(sec);
currDiskSectorNr+=2;
}
void writeSector(sector * sec)
{
for(int i=0,j,k;i<1600;i++)
for(j=0;j<2;j++,k++)
if(k == currDiskSectorNr)
strcpy(clusters[i].sectors[j].rawData , sec->rawData);
currDiskSectorNr--;
}
void readSector(int index, sector * sec)
{
try
{
seekToSector(index);
}
catch(exception ex)
{
throw "Error index input";
}
readSector(sec);
currDiskSectorNr+=2;
}
void readSector(sector * sec)
{
for(int i=0,j,k;i<1600;i++)
for(j=0;j<2;j++,k++)
if(k == currDiskSectorNr)
strcpy(sec->rawData , clusters[i].sectors[j].rawData );
currDiskSectorNr--;
}
};
class TestLevel_0
{
static void printStructSize()
{
cout <<"printing struct size:\n";
cout << "Size of sector -> " << sizeof(sector);
cout << "\nSize of volumeHeader -> " << sizeof(VHD);
cout << "\nSize of DAT -> " << sizeof(DAT);
cout << "\nSize of dirEntry -> " << sizeof(dirEntry);
cout << "\nSize of fileHeader -> " << sizeof(fileHeader);
cout << "\nSize of rootDir -> " << sizeof(rootDirectory) << endl;
}
static void printDiskInfo(Disk & d)
{
VHD * vh = &d.vhd;
cout << "Disk name: " << vh->diskName;
cout << "\nOwner name: " << vh->diskOwner;
cout << "\nProdDate: " << vh->probDate;
cout << "\nformatDate: " << vh->formatDate;
cout << "\nisFormated: " << vh->isFormatted;
cout << "\naddrDataStart: " << vh->addrDataStart;
cout << "\nclusQty: " << vh->clusQty;
cout << "\ndataClusQty: " << vh->dataClusQty;
cout << "\naddrDAT: " << vh->addrDAT;
cout << "\naddrDATcpy: " << vh->addrDATcpy;
cout << "\naddrRootDir: " << vh->addrRootDir;
cout << "\naddrRootDirCpy: " << vh->addrRootDirCpy << endl;
}
static void test_create(string& diskName, string& ownerName)
{//GET STUCK HERE
Disk d;
cout << "Pre created disk: \n";
printDiskInfo(d);
d.createdisk(diskName,ownerName);
cout << "Post created disk: \n";
printDiskInfo(d);
}
static void test_mount(string diskName)
{
Disk d;
cout << "Pre mounted disk: \n";
printDiskInfo(d);
d.mountdisk(diskName);
cout << "Post mounted disk: \n";
printDiskInfo(d);
}
static void test_rwSector(string diskName)
{
Disk d;
sector s;
d.mountdisk(diskName);
cout << "read sectr: \n";
d.readSector(8,&s);
strcpy(s.rawData,"this is write temp secctor");
d.readSector(8,&s);
d.unmountdisk();
}
public:
static void test_0()
{
try
{
string name = "disk 1";
string owner = "Josh & Tzuriel";
printStructSize();
test_create(name,owner);
test_mount(name);
}
catch(exception ex)
{
cout << ex.what() << endl;
}
}
void main()
{
TestLevel_0::test_0();
char a;
cin >> a;
}
答案 0 :(得分:2)
扇区的大小是1kb。 一个集群中有2个扇区,磁盘中有1600个clustor,你试图在堆栈上分配所有这些扇区。
尝试使用堆