运行程序时为何出现"EAccessViolation",请问问题出在哪?

windgolly 2001-11-09 04:30:28
我写了个小程序,编译时没问题,但一运行就出现"EAccessViolation",
然后程序就关闭了.
请问问题出在哪儿?
...全文
7548 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
xhncmec 2001-11-11
  • 打赏
  • 举报
回复
我的也是这种情况,在原编译的目录中,运行正常,单步运行跟踪也正常,在别的目录下单独运行它会出现"EAccessViolation",后来我把project1.obj 拷贝到同一个目录下,程序运行就正常了,请问各位大侠,这是为什么呢?
我已经把
Project-Options-Packages里UnCheck掉"Build with runtime packages"
Project-Options-Linker里UnCheck掉"Use dynamic RTL"
Project-Options-Compile里按一下"Release"按钮
whitelion 2001-11-11
  • 打赏
  • 举报
回复
同意
heavyrain1234(请回答详细点,给分多多) 
一般是地址错误
天涯浪子 2001-11-11
  • 打赏
  • 举报
回复
以上文档来自www.bytamin-c.com的文档中心,在百联美达美卖的《程序员大本营》里有翻译成中文的
天涯浪子 2001-11-11
  • 打赏
  • 举报
回复
文档二:

Access Violations

•Introduction
•Design Time Access Violations
•Hardware Issues
•Software Issues
•Faulty Libraries
•Upgrading C++Builder
•Runtime Access Violations
•Access Violations occurring on Program Exit
•Null Your Pointers!
•Let the IDE Manage!
•caFree Your Forms!
•Random Access Violations (Not on Exit)
•Additional Comments from Users
•Notes on Locking for Updating






Introduction

Access Violations (AVs) are some of the most troublesome errors encountered in Windows programming. Although it is difficult for one article to explain all of the possible causes for these, I will attempt to cover as many known issues as I can. If you are reading this because you are currently experiencing an AV and your final solution is not listed on this page, please forward an email to the author so we can add your experience.

There are two major types of AVs encountered in C++Builder.. runtime and design time. Let’s first discuss the later.

Design Time Access Violations

These are sometimes the easiest to track down but can be hard to actually rid yourself of. Design time AVs are experienced when building, when starting and closing the Builder, or can be experienced in an almost random timing. Several causes exist for these so let’s discuss them.

Hardware Issues

Some video cards, dual processor motherboards, and sound devices can actually cause AVs in C++Builder. Why? Every card in your machine comes with device drivers. Depending on the manufacturer, the version of Windows, and the version of C++Builder used you may experience problems. There are some steps that can be taken to help resolve these issues:

Always use the latest driver for all of the components in your system. If you are using the drivers that came with your version of Windows, chances are you need to get updates from the vendor.

Check resources including the newsgroups at Borland.Com and DejaNews.Com for issues for your particular device. Some video cards have known issues and you might actually need to replace your hardware. It is a good idea to use a video card that is known to have solid and mature drivers. Matrox is a good example of a video device that is known to be solid.

Take the steps necessary to verify that there are no conflicts between your installed devices.

Sometimes lowering the resolution will help stabilize a quirky video card driver.

Insure that if you are using a dual processor motherboard that the step revision for each processor is the same.

Software Issues

Although Windows is the most popular operating system for Intel machines, it has a history of being buggy and unstable. There are ways that you can help your chances of having a more stable programming station, which in turn will help to prevent certain AVs.

Disable Active Desktop on Windows stations that have Internet Explorer (IE) 4.x or higher. Although this feature allows for a more customized desktop, this feature has caused problems with many applications, which led to its demise in IE 5.0.

Although Windows 9X is quite popular, Windows NT 4.0 has proven to be a much more stable environment for almost all Windows coding platforms. I cannot stress enough that this is the environment of choice for the C++Builder programmer.

Ensure that you have installed the latest service packs for NT. With each service pack released, you will find that your NT machine will become more stable.

Reinstall the latest service pack after upgrading drivers for major software packages, including MS Office, IE, and even after an installation of C++Builder. Certain files will often be installed by a driver that had previously been replaced by a service pack. If a service pack asks you to replace a newer file, say no.

It has been our experience that if you have been working on a machine and over time start to experience more and more issues including AVs, reinstalling your OS will not only solve most of those issues but will usually actually increase overall system performance. As more and more software packages, driver updates, and service packs get installed, the DLLs and other critical system files develop version mismatches. A fresh install should be done on all NT workstations annually if possible. This can be a nightmarish task but the rewards are wonderful. When planning a fresh installation, keep in mind any upgrades you may want to do and try to schedule them to occur at the same time.

Faulty Libraries

It is often a good idea to track when new libraries and components are installed and see if there is a correlation to design time AVs. You may want to try removing the latest installed component or library if new AVs are encountered. If the AVs go away, seek support from the vendor.

Also pay special attention to ReadMe files and installation instructions. If you are upgrading a library it may require you to change your include directory or even to modify your make files so that the new and old versions do not conflict. If possible you should always uninstall the prior version before upgrading if the installation program allows for that.

Upgrading C++Builder

Although I promise that I do not work for Inprise and do not get any type of commission, I cannot stress how important it is to stay current with C++Builder. The number of AVs, especially design time violations, drastically decreased when our organization upgraded from C++Builder 3 to 4. Add to that the performance increases and additional resources available, upgrades are quite cost effective in the long run.

Runtime Access Violations

Although these can be a nightmare to track down, you can solve them and they typically do not represent bugs in C++Builder. Before I begin to help you troubleshoot your code, it is important that you read the design time information. Any and all of the suggestions in that section apply to runtime AVs as well. Pay special attention to your include directories on any recently updated libraries as a possible culprit. If these do not solve your issue, lets discuss some programming aspects that should isolate your problem and get you back into production.

AVs Occurring on Exit or Deletion

If you have ever seen your application start spitting out AVs during its exit, then you have shared the frustration of many C++Builder programmers… including myself. These AVs are the hardest to track down since the debugger will usually take you deep into the VCL or actually point to the closing bracket in the Project CPP file. But do not fear. The following should help you get past the worst of the worst in the AV experience.

NULL your Pointers!

One of the biggest causes of Access Violations is an attempt to delete an invalid pointer. This event may occur due to an unintialized pointer or an attempt to delete something twice. If you follow this advice you will eliminate 50% of your AVs in your application. With all pointers, do the following:

After declaring the pointer, set it to NULL. If not, you do not new it right away. If the application exits and a delete is performed, the pointer’s address will be meaningless and you will experience an AV.

After deleting a pointer, set it to NULL. Although the delete command actually clears memory, it does not clear the pointer address. If a subsequent delete is performed on that pointer, it will raise an AV.

Remember that there is nothing wrong with deleting a NULL pointer and nothing bad will come from this.

Let the IDE Manage!

If you create an object that is owned by another object, let the owner do the deleting. Confused? Allow me to explain by example. If you create a panel dynamically and in the new statement you pass the owner as a form (Tpanel MyPanel=new Tpanel(this)), then when the owner is deleted, it will attempt to delete your panel. If you have already deleted it, walla, AV. So whenever you new and object and pass an owner in the constructor, instead of deleting it yourself, let the Builder do it. If you must delete it, make sure you set it to NULL.

caFree Your Forms

If you can, instead of deleting an instance of a dynamically created form, use caFree in its exit event. Although this may not solve your access violation, the result is that you will be able to isolate the cause since the AV will occur on the event instead of on application termination.

Random Access Violations (Not on Exit)

To create a list of programming problems would not only be way too time consuming, but chances are I would not cover the problem you are having so no attempt will be made to do so. Here are a few of the most common problems we have experienced. Hopefully users will help out this article by submitting more. We will also try to add to list so you may want to check back often.

Some of the more common AV coding problems:

An attempt to access a position in a string that is past the length of the string. Example: The string is NULL ("") and an attempt is made to access the first character, myString[1]. See the Tips & Tricks section for an entry titled "Ansi Strings – Preventing AVs" for more information.

Referencing a NULL pointer. This may happen if a pointer is newed in a condition, has not been newed, or if a pointer was deleted prior to it being accessed. Also if a local and extern pointer has the same name, the extern or local was newed but the other is being accessed.


--------------------------------------------------------------------------------

Additional Comments from Users

10/28/1999
mailto:Pbrindle@bmts.com
I agree, Windows NT is the best Windows OS to develop Cbuilder applications. All our applications are developed on NT and we deploy them on Win95/98/NT with no problems at all. NT is rock solid and I never have to reboot my systems no matter how many times I rebuild or compile my projects.



--------------------------------------------------------------------------------

10/28/1999
http://www.bytamin-c.com/Articles/Ungod@Bytamin-C.Com
It might be worthwhile to note in design time for anything up to and including 64M, Microsoft's imagelist control can take a heavy toll on system resources. When these drop to approx 10%, the system starts going haywire. On 9x boxes I recommend running the resource monitor and keeping running applications to a minimum while designing.
Can't stress the accessing null pointers problem enough, in fact, it's usually a good idea to check all pointers before you even decide to do any work with them. This can be done a couple of ways... the best probably being using assert. But even an if(myptr!=NULL) {...}. It might be nice also to point out that for multi-level pointers, that "if" solution can work well too thanks to c's insistence on bugging out of an "if" predicate on it's first false value (short circuit boolean evaluation). I.e. if(myptr!=NULL && myptr->itsptr!=NULL && myptr->itsptr->ptr2!=NULL) {....}.



--------------------------------------------------------------------------------

12/04/1999
http://www.bytamin-c.com/Articles/Pave@Hotmail.Com
I've also noticed that :
int *pArray = new int[2];

pArray[0] = 1;
pArray[1] = 2;
pArray[2] = 2; Overflow!! The array was assigned only 8 bytes...

Doesnt pop the "normal" Access violation screen (the one with the red X) but rather pops a dialog with no icon and also pops the CPU window.. So when you see that you know you just overflowed an array.. "whew"



--------------------------------------------------------------------------------

4/28/2000
xiphias
Tracking Down the Location of Some Avs (from our How-To section).

*** We will be adding to this list in the future.. and you can help! Send me your AV experience to scross@bytamin-c.com and I will update this page. You can help someone too!!

Best of luck!

Scott Cross
天涯浪子 2001-11-11
  • 打赏
  • 举报
回复
Access Violations(简称AVs)错误非常普遍,给你两篇文档看看:

Tracking Down the Location of Some Avs

An av which results from attempting to access a property (or method) of an uninstantiated class can be easily identified if there is not much code to debug. On the other hand, if there is a great deal of code, or if the av occurs somewhere in a loop that iterates many times, the task is a bit more daunting. Luckily, the av messages displayed by windows (and/or cBuilder) can be used to isolate the cause of the invalid memory access. There are two important things to keep in mind for what follows: a.) don't let the hexadecimal notation scare you and b.) Don’t be frightened by the CPU window.

Consider the following code fragment:

TEdit *EditBox;
EditBox->AutoSelect = false;

This is syntactically correct and the compiler won’t complain at all. Of course, the problem comes at runtime when we are greeted with something like "Access Violation at (someaddress) in module Vcl40.bpl. Read of address 000001F4." Try it.

Now consider this fragment:

TEdit *EditBox;
EditBox->AutoSize= false;

Again, the compiler compiles the linker links and we receive another notice from windows at runtime: "Access Violation at (someaddress) in module Vcl40.bpl. Read of address 000001F5."

So what is going on??

Buckled in? Ok. In memory an object is pretty similar to an array so we had better look at an array first.

Consider:

int myIntegerArray[10];
myIntegerArray[0] = 5;
myIntegerArray[1] = 86;

When we assign a value to the 1st position (myIntegerArray[0]) we are in effect adding 0 to the memory location that the compiler allocated for "myIntegerArray". Then we move the value 5 into this memory location. The compiler was kind enough to allocate (reserve) the next 9 int sized memory cells for us as well. So, when we assign the value 86 to myIntegerArray[1] we are in effect adding sizeof(int) to the memory location specified by myIntegerArray and stuffing 86 in. In general, myIntegerArray[n] can be viewed as myIntegerArray + (n*sizeof(int)). The entity (n*sizeof(int)) can (and should) be thought of as an 'offset'.

So what does this have to with access violations?

The 'read of address' values above (000001F4 and 000001F5) are offsets from EditBox! Looking back at the 1st two code snips, cBuilder is kind enough to initialize EditBox to 0. When we try to access a property of EditBox we are in effect adding the offset of the property to the class base pointer (just like with arrays above). But the base pointer (EditBox) is equal to 0! Since 00000000 + offset of AutoSelect (000001F4) is not a user-accessible absolute memory address we get the av.

How can this information be used to solve an av?

First and foremost, the information presented above should increase your general understanding of this variety of av. Secondly, the information dispensed in the access violation message boxes can be used to isolate the high-level code that is causing the problem. Here's how:

1.) Record the address at which the av occurs. This is given above as '(someaddress)'.

2.) Set a breakpoint in the 1st constructor that is executed (the project's main form).

3.) Execute the project.

4.) When execution halts at the breakpoint hit ctrl-alt-c which brings up the CPU window.

5.) Right-click in the top-left-most area which contains the assembler code.

6.) Choose 'Goto Address' from the popup menu.

7.) Type '0x(someaddress)' into the 'Enter Address To Position To' window that pops up and then hit enter.

Using the TEdit example above, you will see:

vcl40.@Stdctrls@TCustomEdit@SetAutoSize$qqr4bool

The meaning is simple. We are in module vcl40 attempting to access TCustomEdit+SetAutoSize. Isolating the high-level perpetrator can now begin. Simply look for an object descending from TCustomEdit

that is accessing the AutoSize property. When you find it, you will most likely have found the high-level line that is causing the av!


Now go tackle those nasty avs!

sncel 2001-11-10
  • 打赏
  • 举报
回复
删除资源文件(*.res)后重新编译,不知我记的对不对,你试试,
我也碰到过的,主要你程序中指定了程序的图标,上述方法我这里可以用,你试试吧,不过脱离编译环境是可以执行的,在编译环境中就会出现这样的问题,你可以加入程序图标编译后,直接运行程序不要在编设环境下执行,到完全可以用时再加入图标编设后就可以了
dycdyc123 2001-11-10
  • 打赏
  • 举报
回复
I agree !!

When you use one Variant you must notice the rule of it!!

heavyrain1234 2001-11-10
  • 打赏
  • 举报
回复
我的经验是:变量或对象的实例,没有被赋直或初始化或被分配空间
就开始用了

解决方法实单步调试
jimmy771020 2001-11-10
  • 打赏
  • 举报
回复
情况具体点。
windgolly 2001-11-10
  • 打赏
  • 举报
回复
补充:
家里和公司用的是两台不同的PC。
windgolly 2001-11-10
  • 打赏
  • 举报
回复
问题的出现是这样的:
我在家里写了一个程序,编译和运行都没问题。
同一个程序,我什么地方也没改。
拿到公司里重新编译:
编译没问题。
可运行时则出现上述问题。
如果按各位大虾所说,我的程序在家里编译的也应该不能运行啊?
不知为何?
wuhuar 2001-11-09
  • 打赏
  • 举报
回复
这是地址访问违规,是自己程序设计方面的问题。
比如你用
int a[10];
int i;
a[i]=1;
如果你的i没有赋值,就会出现这个问题,
当然以上程序编译是没问题的。
windgolly 2001-11-09
  • 打赏
  • 举报
回复
没人遇到过这个问题吗?

13,825

社区成员

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

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