How to avoid common errors and make program efficient.

本文档提供了避免Symbian C++编程中常见错误的建议,并介绍了如何通过两阶段构造等技巧提高程序效率,确保资源正确释放。
How to avoid common errors and make program efficient.

From Forum Nokia Wiki

Jump to: navigation , search

Following are the general tips for avoiding unnecssary and common errors,

and make your program efficient.


Contents

[hide]

[edit] KERN-EXEC 3

Kern-Exec 3 crashes are often caused due to stack corruption or stack Overflow, prefer the use of heap to the stack. Be aware that recursive functions can eat the stack at runtime — this will lead to a Kern-Exec 3 panic.


[edit] Some common errors for application panic

• Failure to have properly added a non-member, heap-allocated variable to the Cleanup Stack. • The ‘double delete’ – e.g. failure to correctly Pop() an already destroyed item from the Cleanup Stack, causing the stack to try to delete it again at a later time. • Accessing functions in variables which may not exist in your destructor;

e.g.

CSomeClass::~CSomeClass()

{

          iServer->Close();

          delete iServer;
 
}

The above statement should always be coded as

CSomeClass::~CSomeClass ()

{

	if (iSomeServer)

	{

	   iServer ->Close();

	   delete iServer;
	
	}
	
}

• Putting member variables on the Cleanup Stack – never do this, just delete them in your destructor as normal.


[edit] Use CleanupClosePushL()

Always use CleanupClosePushL() with R classes which have a Close() method. This will ensure they are properly cleaned up if a leave occurs.

For example:

RFile file;

User::LeaveIfError(file.Open(.....));

CleanupClosePushL(file);

// some code

CleanupStack::PopAndDestroy();


[edit] HBufC

Always set member HBufC variables to NULL after deleting them. Since HBufC allocation (or reallocation) can potentially leave, you could find yourself in a situation where your destructor attempts to delete an HBufC which no longer exists.


You don’t need to use HBufC::Des() to get into an HBufC. All you have to do is dereference the HBufC with the * operator – this is particularly relevant, for example, when passing an HBufC as an argument to a method which takes a TDesC& parameter.


[edit] _L() Macro

Dont use the _L() macro in your code. you should prefer _LIT() instead. The problem with _L() is that it calls the TPtrC(const TText*) constructor, which has to call a strlen() function to work out the length of the string. While this doesn’t cost extra RAM, it does cost CPU cycles at runtime. By contrast, the _LIT() macro directly constructs a structure which is fully initialized at compile time, so it saves the CPU overhead of constructing the TPtrC.

Alternatively, you can use following macros instead of _L():

#define __L(a) (TPtrC((const TText *)L ## a,sizeof(L##a)/2-1))

#define __L8(a) (TPtrC8((const TText8 *)(a),sizeof(a)-1))

#define __L16(a) (TPtrC16((const TText16 *)L ## a,sizeof(L##a)/2-1))

It gets rid of strlen, but still TPtrC constructors are not inline functions.

[edit] TRAP

If you have cause to use a TRAP of your own, do not ignore all errors. A common coding mistake is:

TPAPD(err, SomeFunctionL());

if (err == KErrNone || err == KErrNotFound)

{

// Do something else

}

This means all other error codes are ignored. If you must have a pattern like the above, leave for other errors:

TPAPD(err, SomeFunctionL());

if (err == KErrNone || err == KErrNotFound)

{

// Do something else

}

else

User::Leave(err);


[edit] Cleanup Stack

Do not wait to PushL() things on to the Cleanup Stack. Any newly allocated object (except member variables) should be added to the stack immediately. For example, the following is wrong:

void doExampleL()

{

  	CSomeObject* Object1=new (ELeave) CSomeObject;

	CSomeObject* Object[[Category:Symbian C++]]2=new (ELeave) CSomeObject;

}

because the allocation of Object2 could fail, leaving Object1 ‘dangling’ with no method of cleanup. The above should be:

void doExampleL()

{

	CSomeObject* Object1=new (ELeave) CSomeObject;

	CleanupStack::PushL(Object1);

	SomeObject* Object2=new (ELeave) CSomeObject;
	
	CleanupStack::PushL(Object2);

}


[edit] Don't push objects on the cleanup stack twice

Always remember that functions with a trailing C on their name automatically put the object on the Cleanup Stack. You should not push these objects onto the stack yourself, or they will be present twice. The trailing C functions are useful when you are allocating non-member variables.


[edit] Two-phase construction

Two-phase construction is specially designed to avoid memory leaks, It is essential that you implement this design pattern to avoid memory leaks in your code.For each line of code you write, a good question to ask yourself is ‘Can this line leave?’. If the answer is ‘Yes’, then think: ‘Will all resources be freed?’.


[edit] Descriptors as function parameters

When using descriptors as function parameters, use the base class by default. In most cases, pass descriptors around as a const TDesC&. For modifiable descriptors use TDes&.



[edit] When using Active Objects, be careful of the following things

• There is no need to call TRAP() inside RunL(). The Active Scheduler itself already TRAPs RunL() and calls CActive::RunError()after a leave.
• To this end, you should implement your own RunError() function to handle leaves from RunL().
• Keep RunL() operations short and quick. A long-running operation will block other AOs from running.
• Always implement a DoCancel() function and always call Cancel() in the AO destructor.

[edit] Ensure your application responds to system shutdown events

It is vital that you respond to EEikCmdExit (and any platform-specific events, for example EAknSoftkeyBack and EAknCmdExit on Series 60) in your AppUi::HandleCommandL() method.




[edit] Make use of the Active Object framework wherever possible

Tight polling in a loop is highly inappropriate on a battery powered device and can lead to significant power drain.


[edit] Program compiles for WINS but not for ARMI

Your program compiles for WINS even runs on the emulator but gives errors during ARMI build. Possible reason for this is you have left a space in the header file name i.e. instead of #include "headerfile.h" you've typed #include "headerfile.h ". Just remove that space and the compile again.


[edit] HTTP Posts

In case of HTTP posts with forms always remember to delete the instance of CHTTPFormEncoder. If it is a php script on your server the Form elements are read bottom to top whereas python script reads the Form elements top to bottom. So what may seem to work on php wont work if the scripting language is changed to python. So always:

delete iFormEncoder;

iFormEncoder = NULL;

iFormEncoder = CHTTPFormEncoder::NewL();
内容概要:本文系统性地介绍了基于“断线解环”思想的配电网辐射状拓扑约束建模方法,旨在通过Matlab代码实现,复现顶级EI论文中的核心技术。该方法聚焦于保障配电网在运行过程中维持严格的辐射状结构,防止环路形成,从而提高系统的安全性、稳定性和运行效率。文章深入阐述了如何利用混合整数线性规划(MILP)等优化技术处理复杂的拓扑约束条件,并结合标准配电网络进行仿真验证,特别适用于含分布式电源接入的现代复杂配电网。资源包不仅包含完整的Matlab实现代码,还整合了大量前沿科研方向的相关代码与资料,涵盖微电网优化调度、电动汽车协同管理、风光储联合系统、路径规划、深度学习预测等多个热门领域,并提供YALMIP等建模工具的支持,极大地方便了科研人员的学习、复现与二次开发。; 适合人群:具备电力系统、自动化、电气工程或相关工科专业背景,熟练掌握Matlab/Simulink仿真环境,正在从事电力系统优化、智能电网、分布式能源等领域科研或工程应用的人员,尤其适合研究生、博士生及具有一定科研基础的工程师。; 使用场景及目标:① 深入理解并掌握配电网辐射状拓扑约束的数学建模原理与“断线解环”策略的核心思想;② 成功复现高水平EI/SCI期刊论文中的优化模型与算法流程;③ 借助所提供的丰富案例代码,快速开展微电网经济调度、电动汽车优化、新能源预测、多目标优化等方向的科研项目;④ 熟练运用YALMIP等高级建模语言进行电力系统优化问题的建模、求解与分析。; 阅读建议:建议读者优先关注网盘中提供的完整代码、说明文档及示例数据,严格按照资源目录结构循序渐进地学习,重点剖析“断线解环”在消除环路、保证拓扑可行性方面的具体实现逻辑。务必亲自动手运行、调试和修改Matlab代码,以深化对理论模型与编程实现之间联系的理解。同时,可充分利用文中列举的其他研究主题作为灵感来源,拓展自身的科研视野与创新思路。
代码转载自:https://pan.quark.cn/s/3dad5e95abc6 在数据科学领域,Stata被视作一种应用广泛的统计分析工具,特别是在社会科学与公共卫生研究范畴内具有较高的人气。当运用Stata对数据集进行操作时,保障数据的完整性与精确度是极为关键的一环,因为缺失数据(空缺数据)可能对分析结果的可靠性与有效性造成显著干扰。本文将深入阐释如何在Stata环境下处理数据集中的空缺数据,以确保后续的数据分析能够建立在精确无误的数据基础上。 我们需要明确Stata中空缺数据的表达方式。在Stata系统里,当一个变量的数值未被记录或处于未知状态时,通常会以"."符号进行标识,该符号即代表了空缺数据。空缺数据可能源于有意为之(例如,某些信息未被系统收集),也可能由数据录入失误或数据传输过程中的遗失所导致。不论其成因如何,处理这些空缺数据都是数据整理过程中的一个重要组成部分。 处理Stata数据集空缺数据的技术有多种,以下列举三种基础且实用的策略: 1. 移除包含空缺数据的记录: 这种技术适用于那些不允许任何空缺数据的变量或整体分析。借助`rowmiss(_all)`函数能够检测数据集中是否存在任何空缺数据。`egen mis = rowmiss(_all)`这一行代码会生成一个新变量mis,用以记录每条记录中空缺数据的数量。随后,执行`drop if mis`指令将移除所有至少含有一个空缺数据的记录。以此方式,可以确保保留下来的记录在所有变量上均无空缺数据。 2. 移除特定变量中存在空缺数据的记录: 在某些情形下,可能仅关注特定变量的空缺数据。比如,若变量"vars"存在空缺数据,我们可以运用`drop`指令搭配`if`条件来移除这些记录。指令`dro...
代码下载地址: https://pan.quark.cn/s/a4b39357ea24 在数据结构的研究过程中,图被视为一种极为关键的非线性数据结构,其主要功能在于展现不同对象之间的相互联系。图的结构保存途径主要有两种:邻接矩阵以及邻接表。这两种保存途径各自具备独特的长处与短处,并适用于不同的应用情形。 邻接矩阵本质上是一种二维数组,数组中的各个元素用于标示图中顶点之间是否存在连接。对于无向图而言,邻接矩阵呈现出对称性,即假如顶点i与顶点j之间存在一条边,那么矩阵中的元素`arcs[i][j]`和`arcs[j][i]`均会是1(或具有非零值,用以代表权重)。而对于有向图,邻接矩阵通常是非对称的,仅`arcs[i][j]`有可能为1,此表明从顶点i至顶点j存在一条有向的边。邻接矩阵的优势在于,检索任意两个顶点之间是否存有边的时间复杂度仅为O(1),然而它的劣势在于空间利用效率不高,特别是在图呈现稀疏状态时(边的数量远远小于顶点数量平方的值)。 邻接表则提供了一种更为节省空间的保存方法,它为每一个顶点维持一个链表,链表中的各个节点代表了与该顶点相接的所有的边。每个链表节点包含了相邻顶点的索引(或资讯)以及边的权重值。邻接表在应对稀疏图时表现出更高的效率,因为它仅存储现实中存在的边。探寻一个顶点的所有邻接顶点的时间复杂度为O(degree(v)),其中degree(v)是顶点v的度,即与v相连接的边的数目。 在前述的实验活动中,包含了两个核心任务: 1. 将一个指定的有向图从邻接矩阵的格式转换为邻接表的格式,反之亦然。 2. 构思一套程序,让用户能够手动输入图的相关信息,然后将其转变为另一种保存格式。 在采用C语言进行实现时,`AdjMatrix`被定义为一个二维的...
下载代码方式:https://pan.quark.cn/s/a4b39357ea24 冒泡排序算法是一种入门级的排序方法,其核心机制在于反复地扫描整个待整理的元素序列,依次地对照邻近的两个元素,并在必要时进行位置的调换,直至整个序列呈现有序状态。在此过程中,数值较大的元素会逐步向序列的顶端移动,如同气泡浮起一般,因此该算法被命名为“冒泡排序”。 当具体执行冒泡排序时,一般会借助一个for循环来管理外部的遍历流程,而内部的相邻元素对比及位置调整则由另一个for循环负责。以下是一个基础的冒泡排序算法在Python语言中的具体编写: ```python def bubble_sort(nums): n = len(nums) for i in range(n): # 若本轮遍历无需继续执行冒泡操作,可提前终止 if not swapped: break swapped = False for j in range(n - i - 1): # 当前一个元素比后一个元素大时,则进行位置交换 if nums[j] > nums[j + 1]: nums[j], nums[j + 1] = nums[j + 1], nums[j] swapped = True return nums ``` 在这个算法设计中,`swapped`变量用于检测是否发生了元素交换,如果某一轮遍历结束后未进行任何交换,表明序列已达到排序完成的状态,此时可以提前终止算法。 在特定题目要求中,“输入n个数采用冒泡排序法从大到小排序”实际上是对冒泡排序方法的一种特殊运用,即需要对序列进行降序的排列。要达成这一目标,只需对冒泡排序的比较逻辑进行细微的修改即可:将原来的`if nums[j] > nums[...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值