请大家帮忙,同样的代码,后来运行出错了

BorlandXBuilder 2004-07-06 10:10:45
我写了一个读写串口的程序,原来运行没错,但是在一次读取数据越界后每次读数据的时候就会出现如下错误:
Project test.exe raised exception class EAccess Violation with message "Access Violation at address 40009720 in module 'rtl60.bpl',Read of address c1942603" process stopped.use step or run to continue.

请问四怎么回事啊,急死了
...全文
186 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
gunney 2004-07-08
  • 打赏
  • 举报
回复
老季比较猛
BorlandXBuilder 2004-07-08
  • 打赏
  • 举报
回复
谢谢了,和jishiping(JSP 季世平) 说的一样,谢谢了!!!
BorlandXBuilder 2004-07-06
  • 打赏
  • 举报
回复
不会的,难道要让我把代码重新写一遍吗?
hear_rain 2004-07-06
  • 打赏
  • 举报
回复
那fDeal_With_Data 的temp是不是能保证是合法的取值?比如说,不会是负数什么的
BorlandXBuilder 2004-07-06
  • 打赏
  • 举报
回复
25,写错了,不好意思
hear_rain 2004-07-06
  • 打赏
  • 举报
回复
在这个函数fReceive_Data里,

//初始化ReceiveData[24]
for (int i = 0; i < 25; i ++)
{
ReceiveData[i] = 0xFF;
}

你这个数组ReceiveData的大小到底是24还是25?
「已注销」 2004-07-06
  • 打赏
  • 举报
回复
我以前写过一个程序,用Release编译也出现你那种问题,但是用Debug编译就什么事都没有
怪~~
BorlandXBuilder 2004-07-06
  • 打赏
  • 举报
回复
不过我感觉奇怪的是:出错后,以后无论什么情况都出错了,就是返回出错前的情况也照样出错,我写程序的时候一直用着CodeGuard,没有报错的,这是那个函数的代码:

//---------------------------------------------------------------------------
void __fastcall TfrmMain::fDeal_With_Data (int iMachIndex)
{
//接收数据
int temp;
if (iMachIndex == 0)
{
temp = iUsedCount - 1;
}
else
{
temp = iMachIndex - 1;
}

fReceive_Data (temp);

if (bConnectNormal[temp]) //收到的是正常数据
{
iConnectError[temp] = 0;
fSave_Data (ReceiveData, temp);
TeThemeStatusBar1->Panels->Items[1]->Text = IntToStr (MachUsed[temp][0]) + "#机组" + IntToStr (MachUsed[temp][1]) + "#内机" + "通讯正常";
}
else if (bReceiveError[temp]) //收到的是通讯故障数据
{
iConnectError[temp] = 0;
TeThemeStatusBar1->Panels->Items[1]->Text = IntToStr (MachUsed[temp][0]) + "#机组和" + IntToStr (MachUsed[temp][1]) + "#内机" + "通讯故障";
}
else if (iConnectError[temp] > 5) //通讯错误次数超过5次,则和集中控制器通讯故障
{
TeThemeStatusBar1->Panels->Items[1]->Text = IntToStr (MachUsed[temp][0]) + "#机组" + "和计算机之间通讯故障";
}

fSend_Data (iMachIndex);
}
//---------------------------------------------------------------------------

void __fastcall TfrmMain::fReceive_Data (int iMachIndex)
{
//初始化ReceiveData[24]
for (int i = 0; i < 25; i ++)
{
ReceiveData[i] = 0xFF;
}

bConnectNormal[iMachIndex] = false;

int ByteNum;
RxBuff = MSComm1->Input;
ByteNum = RxBuff.ArrayHighBound (1); //取得接收到的字节数 = ByteNum + 1

// 在通讯数据窗口显示接收到的数据
if (ByteNum >= 0)
{
fShow_Receive_Data (RxBuff, ByteNum);
}
else
{
//如果接收到的数据长度小于0 ,则判断为通讯错误一次
//通讯错误计数器加一,本次通讯结束,进行下一个机组的通讯
iConnectError[iMachIndex] ++;
return;
}

int iPosition_1 = -1;

//寻找引导码并用iPosition_1标识其位置
for (int i = 0; i <= ByteNum - 9; i ++)
{
ReceiveData[0] = RxBuff.GetElement (i);
ReceiveData[1] = RxBuff.GetElement (i + 1);

//如果引导码正确,给iPosition_1赋值并退出循环
if (ReceiveData[0] == 0x7E && ReceiveData[1] == 0x7E)
{
iPosition_1 = i;
break;
}
}

//如果没有找到引导码,判断为通讯错误一次
//通讯错误计数器加一,本次通讯结束,进行下一个机组的通讯
if (iPosition_1 == -1)
{
iConnectError[iMachIndex] ++;
return;
}

//如果收到的有效数据(从找到引导码到数据完)的长度小于最短通讯包长度
//则判断为通讯错误,通讯错误计数器加一,本次通讯结束,进行下一个机组通讯
if (ByteNum < iPosition_1 + 8)
{
iConnectError[iMachIndex] ++;
return;
}

ReceiveData[0] = RxBuff.GetElement (iPosition_1); //0x7E
ReceiveData[1] = RxBuff.GetElement (iPosition_1 + 1); //0x7E
ReceiveData[2] = RxBuff.GetElement (iPosition_1 + 2); //机组地址
ReceiveData[3] = RxBuff.GetElement (iPosition_1 + 3); //计算机地址
ReceiveData[4] = RxBuff.GetElement (iPosition_1 + 4); //包信息
ReceiveData[5] = RxBuff.GetElement (iPosition_1 + 5); //本包长度
ReceiveData[6] = RxBuff.GetElement (iPosition_1 + 6); //标识控制器的身份信息
ReceiveData[7] = RxBuff.GetElement (iPosition_1 + 7); //标识控制器的身份信息
ReceiveData[8] = RxBuff.GetElement (iPosition_1 + 8); //命令字

int iLength;
iLength = RxBuff.GetElement (iPosition_1 + 5);

//如果长度不够
if (ByteNum < iPosition_1 + ReceiveData[5])
{
iConnectError[iMachIndex] ++;
return;
}

//如果长度不对
if (iLength != 18 && iLength != 5)
{
iConnectError[iMachIndex] ++;
return;
}

//收到的数据中地址码和实际的地址码不符合
if (ReceiveData[3] != MachUsed[iMachIndex][0])
{
iConnectError[iMachIndex] ++;
return;
}

//没有错误,开始接收分析数据
if (ReceiveData[8] == 0x82)
{
//收状态信息
for (int i = 0; i <= iLength + 5; i ++)
{
ReceiveData[i] = RxBuff.GetElement (iPosition_1 + i);
}

//校验码
CheckSum = ReceiveData[2];

//计算实际的校验码
for (int i = 3; i < iLength + 5; i ++)
{
CheckSum = CheckSum ^ ReceiveData[i];
}

//校验码正确
if (CheckSum == ReceiveData[iLength + 5])
{
bConnectNormal[iMachIndex] = true; //成功收到信息
}
}
else if (ReceiveData[8] == 0x84)
{
//收显示板和主板通讯故障信息
for (int i = 0; i <= iLength + 5; i ++)
{
ReceiveData[i] = RxBuff.GetElement (iPosition_1 + i);
}

//校验码
CheckSum = ReceiveData[2];

//计算实际的校验码
for (int i = 3; i < iLength + 5; i ++)
{
CheckSum = CheckSum ^ ReceiveData[i];
}

//校验码正确
if (CheckSum == ReceiveData[iLength + 5])
{
bReceiveError[iMachIndex] = true; //成功收到通讯错误信息
}
}

MSComm1->InBufferCount = 0;
}
//---------------------------------------------------------------------------
jishiping 2004-07-06
  • 打赏
  • 举报
回复
“说代码有问题,可是一样的代码以前从来没有出过错误的”
--------------------------------------------------------------
这样是很正常的。代码有错,不是说每次运行到这儿都会出错!如果每次运祥到都会出错,
那么程序的bug一下子就查出来呢,也不会出现每个 软件都有bug了。比如有些错误,是没
有给变量赋初始值,那么变量就是随机值了(好像编译时就决定了)。如果这个随机值比较
好,那么就不会出错,但是如果重新编译一下,随机值不好,就可能导致错误。

当然了,我不是说你这儿就是变量没有赋初始值,我只是举个例子说明你的这种情况。对于
内存越界,那么此时就可能改变了其它变量的值,其它变量的值变成了一个你不期望的数,
从而就可能跟着导致其它的地方跟着出错了。
hear_rain 2004-07-06
  • 打赏
  • 举报
回复
用一下CodeGuard,说不定有意想不到的效果
jone7319 2004-07-06
  • 打赏
  • 举报
回复
多半与内存有关,有没有用指针没new的情况?
BorlandXBuilder 2004-07-06
  • 打赏
  • 举报
回复
不是,只有那一次越界,后来都没有越界,而且如果在那个函数开始设个断点,单步执行一遍那个函数后在继续运行就不出错了,我重新启动CB后还是一样,说代码有问题,可是一样的代码以前从来没有出过错误的
3996906 2004-07-06
  • 打赏
  • 举报
回复
不行就重起机器
你程序里面的代码可能有问题
ktcserver 2004-07-06
  • 打赏
  • 举报
回复
重新启动C++Builder
hear_rain 2004-07-06
  • 打赏
  • 举报
回复
你既然知道有一次读取越界就去改那儿啊
jishiping 2004-07-06
  • 打赏
  • 举报
回复
那就是说,你用下标访问AnsiString的某个字符时,下标出界了。这种情况,是VCL检查下标
的合法性时,发生的抛出(异常),CodeGuard 是不会报告错误的。比如:
AnsiString str="123";
char c = str[256]; // 这儿下标256是非法的,就会发生楼主说的错误,但是CodeGuard不
// 会报错的(因为没有发生实际的越界访问)。
char d = str.c_str()[256]; // 这样写(直接访问内存数据),就不会出现楼主的错误信
// 息,但是 CodeGuard 就会报错。注意,AnsiString 会预
// 先多分配一些内存,所以这儿的数字要大一点,如果是
// d = str.c_str()[4]; CodeGuard 就不会报错

所以,楼主要检查上面代码中通过下标访问AnsiString的字符的代码,看看下标是否合法。
BorlandXBuilder 2004-07-06
  • 打赏
  • 举报
回复
在出错的时候停到了dstring.h文件中的
char& __fastcall operator [](const int idx)
{
ThrowIfOutOfRange(idx); // Should Range-checking
//be optional to avoid overhead ??
Unique(); // Ensure we're not ref-counted
return Data[idx-1];
}

ThrowIfOutOfRange(idx); 这一行了

在编译的时候有一个警告:
[C++ Warning] Dialogs.hpp(437): W8058 Cannot create pre-compiled header: initialized data in header

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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