您的位置:程序门 -> c/c++ -> c++ 语言



在接收函数里的接收数组是否需要优化?


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


在接收函数里的接收数组是否需要优化?
发表于:2008-01-23 09:27:39 楼主
tcp的接收函数:
char   buffer[255];
从socket接收数据到buffer里
将buffer复制到成员变量vector里,现在或稍后一起处理

请问:是否有必要将buffer设置为成员变量?

首先,排除设为static,因为可能有多个线程在同时执行,搞乱了
其次,不设为成员变量是因为从语义上说,它就是一个局部变量,多增加一个成员变量,增加理解难度
最后,如果设为成员变量,则每次有数据来时,不用多余分配内存,提高效率,增加安全性

这个问题,说大不大,说小不小
这种情况做过tcp编程的应该都碰到过,请问您如何取舍?
发表于:2008-01-23 09:30:421楼 得分:0
不用,栈上分配内存是最快的,无论多大,只要大小不过vc的限制,分配时间都一样,

发表于:2008-01-23 09:32:592楼 得分:0
c/c++ code
char buffer[255]; 这个是在栈上申请,只需要偏移一下指针,速度和很快 但如果你用 char* buffer = new char[255]; 这个是在堆上申请,就慢了
发表于:2008-01-23 09:37:143楼 得分:0
了解,谢谢了,原来我还老为这个问题担心呢,呵呵

如果是几k呢?我记得在有些书上说,如果几k的话,最好用new的啊,这又是什么道理?
发表于:2008-01-23 09:43:454楼 得分:0
  设置成成员变量,这样内存分配比较合理,只需一次分配,安全性上也有保障
发表于:2008-01-23 09:45:025楼 得分:0
个人认为
设置buffer为临时变量,而不是成员变量
是为了降低软件相关度;另外lz可以查看
tcp接收函数,也许会找到满意的答案
发表于:2008-01-23 09:45:396楼 得分:0
了解,谢谢了,原来我还老为这个问题担心呢,呵呵  

如果是几k呢?我记得在有些书上说,如果几k的话,最好用new的啊,这又是什么道理?

------

如果是tc   数大小限制好象是   64k

如果是vc   那么是 1m   (这个可以改)

发表于:2008-01-23 09:47:197楼 得分:0
栈毕竟是栈,大小总有一定限制的。pc上的限制我不清楚;嵌入式里通常都比较小,像手机,一个task的栈通常在16k以下,对于几k的内容,当然最好使用动态分配了(或者全局、static之类,尽量不在栈上占用太多)~
发表于:2008-01-23 10:05:048楼 得分:0
tcp编程,学习。
发表于:2008-01-23 10:23:019楼 得分:0
栈毕竟是栈,大小总有一定限制的。pc上的限制我不清楚;嵌入式里通常都比较小,像手机,一个task的栈通常在16k以下,对于几k的内容,当然最好使用动态分配了(或者全局、static之类,尽量不在栈上占用太多)~

----

我是临时用一下,不是长期占用,另外我是在pc上用,这个应该不用担心.
我主要担心的是非常频繁的申请释放栈上的内存,到底会不会对程序的性能有影响
发表于:2008-01-23 10:29:2710楼 得分:0
几k的栈,   在pc的用户程序里不必担心.   一般64k以内的数组,   可以放心的在栈上开.
只要栈没溢出,   那些空间不用白不用.   理论上比堆上的还快,   还不用担心内存泄漏的问题.
发表于:2008-01-23 10:38:5011楼 得分:0
我是临时用一下,不是长期占用,另外我是在pc上用,这个应该不用担心.  
我主要担心的是非常频繁的申请释放栈上的内存,到底会不会对程序的性能有影响

----

栈上的分配释放,效率比动态申请高很多的。栈变量的使用归还,就只是esp指针的增减,因而1楼说“分配时间都一样”;而堆的申请释放,需要经过api,使用相应的内存管理算法~   使用栈和堆,分配释放次数一样的话,个人觉得选栈变量合适。
发表于:2008-01-23 10:58:4112楼 得分:0
win32   下不是分配时间都一样吧,   是   o(n/4k)   的,   对每页内存要读一次(_chkstk),   不然可能gp   ..   当然正常情况下比堆快得多,   不过当数组特别大的时候,   还真不一定比堆快,   偶尝试着自己管理堆的代码,   分配大概需要400-500时钟周期...
发表于:2008-01-23 11:14:4313楼 得分:0
win32   上一样的只是操作   esp   的值,   _chkstk   是   vc   debug   加的内容吧
发表于:2008-01-23 11:31:3514楼 得分:0
不是,   win32   的内存管理就是这样子的..
发表于:2008-01-23 11:39:1715楼 得分:0
mlee79  
 
你说的     _chkstk   在哪里?


c/c++ code
int _tmain(int argc, _tchar* argv[]) { 004113a0 push ebp 004113a1 mov ebp,esp 004113a3 mov eax,28d4h // 不就这里偏移就可以了 004113a8 call @ilt+70(__alloca_probe) (41104bh) 004113ad push ebx 004113ae push esi 004113af push edi 004113b0 lea edi,[ebp-28d4h] 004113b6 mov ecx,0a35h 004113bb mov eax,0cccccccch 004113c0 rep stos dword ptr es:[edi] char buffer[10240]; return 0; 004113c2 xor eax,eax }
发表于:2008-01-23 12:44:4416楼 得分:0
mlee79说的有道理。
_chkstk   routine  
called   by   the   compiler   when   you   have   more   than   one   page   of   local   variables   in   your   function.
remarks
_chkstk   routine   is   a   helper   routine   for   the   c   compiler.   for   x86   compilers,   _chkstk   routine   is   called   when   the   local   variables   exceed   4096   bytes;   for   x64   compilers   it   is   4k   and   8k   respectively.


chiyer为啥不把004113a8     call                 @ilt+70(__alloca_probe)   (41104bh)   里面的代码再打印出来?估计里面会有_chkstk。


我的看法,很可能_chkstk是vc的搞法,vc编译器的行为。
alloca最简单的一种做法就是减减esp,虽然不安全,但是效率很高。

发表于:2008-01-23 12:56:1217楼 得分:0


参阅网上搜来的这篇文章,原来加入_chkstk是为了commit新的page的,难怪我想不通微软在吃饱饭撑的没事干,非要把alloca复杂化。
发表于:2008-01-23 13:34:4218楼 得分:0
__alloca_probe   ==   _chkesp   ....

发表于:2008-01-23 13:38:1019楼 得分:0
__alloca_probe   是   _chkesp   的别名   ...   _alloca   同样要调用   __alloca_probe   ..
发表于:2008-01-23 13:39:3820楼 得分:0
mlee79  

:p

不好意思,偶的错
发表于:2008-01-23 14:37:2521楼 得分:0
_chkesp怎么可能等于__alloca_probe?
我的看法是:__alloca_probe就是相当于以前的sub   esp,0xxxxxh的一个安全版本。
_chkesp是检查stack是否被破坏的,应该不可能具有分配栈空间的功能吧?
_alloca和__alloca_probe的关系还没搞清楚,不知道是不是一个非安全和安全栈分配的区别(从probe上猜的),
现在抛弃使用cpp了,等我回家在vs2005上再查查。
assembly code
004113a3 mov eax,28d4h ;传参 004113a8 call @ilt+70(__alloca_probe) (41104bh) ;记得vc6或者gcc里面都是直接sub esp, 0xxxxxh完事,所以容易造成溢出



附网上google来的话

stacking   verification   with   _chkesp
from   visual   c++   6.0   onwards,   the   visual   c++   compiler   has   provided   the   /gz   compiler   option,   which   is   intended   to   assist   in   finding   release-build   errors   whilst   in   debug   builds.   it   introduces   auto-initialization   of   local   variables   and   various   call-stack   validations.   part   of   its   mechanism   lies   in   the   implicit   calling   of   a   crt   function   called   _chkesp(),   which   validates   the   esp   register   as   part   of   its   stack   checking   on   the   entry   and   exit   of   (most)   function   calls.   the   signature   of   the   function   is   as   follows:


发表于:2008-01-23 14:45:0922楼 得分:0
偶的神啊,   crt代码都是公开的,   你不会自己去看啊,   怎么   __alloca_probe   就不能等于   _chkesp   了   ...

assembly code
labelp _alloca_probe, public labelp _chkstk, public push ecx ; save ecx cmp eax,_pagesize_ ; more than one page requested? lea ecx,[esp] + 8 ; compute new stack pointer in ecx ; correct for return address and ; saved ecx jb short lastpage ; no ;------------ probepages: sub ecx,_pagesize_ ; yes, move down a page sub eax,_pagesize_ ; adjust request and...
发表于:2008-01-23 14:50:3023楼 得分:0
搞错,   写成   chkesp   了,   应该是   chkstk   ....   唉   ...   丢人   ...
发表于:2008-01-23 15:16:2724楼 得分:0
晕,难怪突然冒出个chkesp让我莫名其妙。

手头除了java还是java,没有vc,没有crt源码。

回去看看_alloca_probe和_chkstk,我一直认为_chkstk是没有分配栈空间的功能的。


发表于:2008-01-23 15:32:0825楼 得分:0
_chkstk   不分配空间,   是为了commit新的page的,   esp   -=   n   是分配空间的...  


快速检索

最新资讯
热门点击