w******t 发帖数: 241 | 1 【 以下文字转载自 CS 讨论区 】
发信人: webcraft (此处不留爷,自有留爷处;处处不留爷,爷, 信区: CS
标 题: 请教一个程序调用的内存问题
发信站: BBS 未名空间站 (Sat Sep 8 11:10:10 2007)
我现在在做一个嵌入式系统的程序,其中一个中断会调用一function A,然后function
A又会调用function B,function B 调用C, 一直这样有6个嵌套的调用,我想请问一
下这样函数是不是会不停地在stack上面开销内存(包括函数本身以及函数内申明的局
部变量),这些内存会一直被占用到函数调用结束。像这样地情况,有没有更好的程序
架构能够避免这样的问题。
另外还有一个问题想请教,如果我在某个子函数中申明了指针,并且用malloc开了内存
空间,函数完结的时候free了空间,想请问一下函数调用结束返回之后,这个指针是不
是被自动设置为NULL(我想是这样,因为这个指针是局部变量)?谢谢大家 |
|
x****u 发帖数: 44466 | 2 你误会了,我这个例子里面a根本不是global的,相反,它是局部变量。
这个mutex是给第二个进程用的,而不是作为线程互斥对象。我举这个例子是说明什么
场合下volatile有意义。第二个程序可以用OS功能suspend第一个进程,然后搜索a的值
,接着修改它。
如果一个变量只对单一程序内有意义,我们不应该阻止它被优化。
opaque)
g
th
i
ac
存在
的值 |
|
p*********t 发帖数: 2690 | 3 Xentar当然是对的,局部变量和全局变量的区别,出了作用范围就会被释放。 |
|
B********r 发帖数: 397 | 4 但我试了一下,如果在fun1里面用 char *str="ABC"确实就没问题了,如果局部变量消
失的话,这个str pointer不是应该也没法指向变量了么?还是说“ABC“属于const
variable所以不会随着返回而消失? |
|
b*******s 发帖数: 5216 | 5 在编译器优化前,第一个要多一个局部变量分配
优化后我感觉可能是一样的,某些场合都不需要生成任何临时变量 |
|
d*******r 发帖数: 3299 | 6 记得以前王垠blog上讨论过这个
=================================================
http://www.douban.com/note/269210328/
其实要达到纯函数式语言的这种“纯”的效果,你根本不需要使用像 Haskell 这样完
全排斥“赋值语句”的语言。你甚至不需要使用 Lisp 这样的“非纯”函数式语言。你
完全可以用 C 语言,甚至汇编语言,达到同样的效果。
我只举一个非常简单的例子,如果你在 C 语言里面定义如下的“函数”。虽然函数体
里面含有赋值语句,它却是一个真正意义上的“纯函数”:
int f (int x) {
int y, z;
y = 2 * x;
z = y + 1;
y = z / 3;
return y;
}
这是为什么呢?因为它计算的是数学函数 (2x+1)/3 。你给它同样的输入,肯定会得到
同样的输出。函数里虽然对 y 和 z 进行了赋值,但这种赋值都是“局部”的,它不会
在函数里留下“状态”。所以这个函数虽然使用了被“纯函数程序员”们唾弃的“赋值
语句”,它仍然完全的... 阅读全帖 |
|
C******8 发帖数: 501 | 7 还有并发问题,check完null要访问的时候可能被重置了,因为是成员变量,不是局部
变量 |
|
y**b 发帖数: 10166 | 8 研究了一下智能指针,在这里唯一的好处就是不需要完整类型了。
如果有完整类型,没看出一般情况下智能指针有什么好处,直接管理内置指针很健壮。
实际上智能指针因为引用计数的缘故,大大增加了复杂程度:
shared_ptr如果作为局部变量,在超出作用域时被销毁;如果是唯一引用,则其所指向
的对象也被销毁,所占用的内存会被释放;如果不是唯一引用,则内存不会释放。你看
这有多复杂。
举个例子,一个类有这样一个成员变量:含有智能指针shared_ptr的向量。那么不同成
员函数按一定顺序使用、拷贝或赋值这(整)个向量,会导致引用计数反反复复变化,指
针什么时候存在,什么时候销毁,简直是个灾难了。比如在一个成员函数里面生成一个
新的智能指针,那么在该成员函数之外该智能指针被释放;若将该智能指针加入到向量
,则在该成员函数之外该智能指针不被释放。这种情况,还不如管理内置指针清晰健壮
啊。而且还要保证shared_ptr在无用之后进行手动释放,否则浪费内存。
感觉智能指针只有保证销毁自己一个好处,带来的底层状态变化实在够繁复,没见比直
接管理内置指针更容易。 |
|
w******t 发帖数: 241 | 9 【 以下文字转载自 CS 讨论区 】
发信人: webcraft (此处不留爷,自有留爷处;处处不留爷,爷, 信区: CS
标 题: 请教一个程序调用的内存问题
发信站: BBS 未名空间站 (Sat Sep 8 11:10:10 2007)
我现在在做一个嵌入式系统的程序,其中一个中断会调用一function A,然后function
A又会调用function B,function B 调用C, 一直这样有6个嵌套的调用,我想请问一
下这样函数是不是会不停地在stack上面开销内存(包括函数本身以及函数内申明的局
部变量),这些内存会一直被占用到函数调用结束。像这样地情况,有没有更好的程序
架构能够避免这样的问题。
另外还有一个问题想请教,如果我在某个子函数中申明了指针,并且用malloc开了内存
空间,函数完结的时候free了空间,想请问一下函数调用结束返回之后,这个指针是不
是被自动设置为NULL(我想是这样,因为这个指针是局部变量)?谢谢大家 |
|
t****a 发帖数: 1212 | 10 R在运行效率上是有很多坑,不小心就掉进去了。关于R的并行计算以及大数据操作可以
参考
http://cran.r-project.org/web/views/HighPerformanceComputing.ht
R是免费的,SAS是要付钱的。R是一种语言,SAS就是个tool。总得有几个亮点,否则谁
用阿?
---------------------------
某种程度上说,R是给程序员用的,SAS是给统计师用的,客户不一样。
R有众多的第三方包,有最新的东西,这点SAS完全比不上,SAS就是个古董。
R和linux其他工具整合的很好。如果觉得它不够快,那么推荐配合其他工具一起使用。
1. 小数据直接用R
2. 中等规模数据用awk, python之类配合R
3. 大规模数据用hadoop cluster配合R streaming
在我的工作中,通常处理大规模数据,做aggregation的是其他语言,R是最后一步。
------------------------
既然知道R没有pass by reference,为什么还要传那么多大变量呢?用全局或者可以访
问的局部变量不就可以... 阅读全帖 |
|
t****a 发帖数: 1212 | 11 R在运行效率上是有很多坑,不小心就掉进去了。关于R的并行计算以及大数据操作可以
参考
http://cran.r-project.org/web/views/HighPerformanceComputing.ht
R是免费的,SAS是要付钱的。R是一种语言,SAS就是个tool。SAS总得有几个亮点,否
则谁肯花钱阿?
---------------------------
某种程度上说,R是给程序员用的,SAS是给统计师用的,客户不一样。
R有众多的第三方包,有最新的东西,这点SAS完全比不上,SAS就是个古董。
R和linux其他工具整合的很好。如果觉得它不够快,那么推荐配合其他工具一起使用。
1. 小数据直接用R
2. 中等规模数据用awk, python之类配合R
3. 大规模数据用hadoop cluster配合R streaming
在我的工作中,通常处理大规模数据,做aggregation的是其他语言,R是最后一步。
------------------------
既然知道R没有pass by reference,为什么还要传那么多大变量呢?用全局或者可以访
问的局部变... 阅读全帖 |
|
|
p*********t 发帖数: 2690 | 13 fun1()在返回一个局部变量的地址,所以输出的是這個地址的值,因为fun1()的局部变
量在函数结束时消失,那个地址可能又被分配了新的值,所以是乱码。
要想输出abc,可以在fun1()的str设为static,这样即使fun1()函数结束,str[]还是在
内存存在。
char *fun1() {
static char str[]="ABC";
return (str);
}
有下面这段code, 为什么fun1()输出乱码, 而fun2()输出正确: ABC.
====== code ============
#include
int main() {
char *fun1(), *fun2();
printf("%s\n%s\n", fun1(), fun2());
return 0;
}
char *fun1() {
char str[]="ABC";
return (str);
}
char *fun2() {
char (*str)[]="ABC";
return (str);
... 阅读全帖 |
|
|
e****9 发帖数: 316 | 15 来自主题: JobHunting版 - 问道编程题 整个这个一道改错题.返回局部变量是其中的一个,这个好解决.
现在解决不了的就是前面提到的
Is there a different way to write line 500 which preserves the same
effective prototype? If so, what is it?
想了想,好像没有什么其他得方法来定义这个函数,唯一能想到的就是前面加个inline |
|
y**i 发帖数: 1112 | 16 应该是对的,而且我记得debug版本下局部变量好像连续运行的话每次值好像还一样,
release版本下就完全随机了,我记得以前做实际项目的时候碰到过这种问题 |
|
s********g 发帖数: 60 | 17 499 /*-------- GetSomeIDs-----*/
500 int * GetSomeIDs()
501 {
502 int ids[8];
503-550 /* The ids are defined here */
551 return ids;
552 }
不能这么写吧,ids是局部变量,function结束后指针为junk,用heap内存存储才好 |
|
c******e 发帖数: 545 | 18 这种函数都是__cdecl调用,参数从右向左压栈,主调函数清栈。
format string在最左(printf)或次左(fprintf,sprintf...),所以用[BP]访问的时候
位置可预测,然后根据format string生成每个参数的偏移地址。
一般来说函数调用大致顺序(__cdecl)是:
1.主调函数从右到左压参数
2.建立栈帧
1)保存BP(32位下EBP,下同)push bp
2)保存当前栈位置:mov bp,sp
因为BP和SP默认同时用栈段(SS),用BP上可访问参数,下可访问局部变量,一般不用
SP,因为SP总是在变。
3.函数体
4.恢复bp:mov sp,bp pop bp
4.函数返回
5.主函数清栈(xxx是参数大小):add sp,xxx
时间太久可能细节不太准确,不过大致过程应该差不多,可以使用变长参数的两个决定
因素是:1. 右到左压栈 2. 主调函数清栈 |
|
c******e 发帖数: 545 | 19 如果有局部变量的话还要修改sp来reserve空间:
sub sp, yyy |
|
l*********8 发帖数: 4642 | 20 vector list; 是局部变量,离开函数后就不存在了
可以改成:
vector * list = new vector; |
|
d**********x 发帖数: 4083 | 21 只能使用 ! ~ & ^ | + << >>
可以用 =,可定义局部变量,字长32bit,右移是算数右移,不许cast
常量只能在0~0xff之间。实际上一般面试不会有这个约束,就忽略吧
1. int isAsciiDigit(int x);
如果x是'0'~'9',返回1,否则返回0
2.int anyEvenBit(int x);
如果任何偶数位上有1返回1 (1 --> 1, 2 --> 0)
3.int copyLSB(int x);
如果x & 1,则返回0xffffffff,否则返回0
4.int leastBitPos(int x);
5.int divpwr2(int x, int n);
输出 x / pow(2, n);,n非负。
6.int conditional(int x, int y, int z);
相当于x ? y : z
7.int isNonNegative(int x);
非负数返回1
8.int isGreater(int x, int y);
如果x > y,返回1
9.int absVal(int x);
返回x的绝对值
10.int isP... 阅读全帖 |
|
j********g 发帖数: 80 | 22 楼上的代码解释了你的疑问。大概就是那个意思,可以自定义结构,也可以在每次调用
的时候创建个局部变量。 |
|
p*****2 发帖数: 21240 | 23
scala确实把java很多垃圾的地方改进了。平时就觉得java那些地方恶心,结果一看
scala全整好了。使用eclipse,不过不是很好用。我调试只能看到局部变量。 |
|
p*****p 发帖数: 379 | 24 你这在C++里也不行啊,除非你把函数参数定义成引用
removeNode(Node * &toRemoved)
这样的
java里可以把返回值定义成Node
if (toRemoved == null) return null;
if (toRemoved->next == null) return null;
toRemoved->next = removeNode(toRemoved->next);
return toRemoved;
你光把最后一个node改成null只是影响了局部变量而已,上一个node的next还是原来的
指向
list |
|
w****a 发帖数: 710 | 25 10分钟面经系列,这次是T家。
上次FB二面终于如期收到拒信,move on了。T家的一面希望大家bless啊。
刚开始给我一分钟时间问了我两个behavior问题,一个是我现在在做什么,一个是why
T家。
然后就开collabedit了,就写了一道题。题很简单,板上的XDJM们相信都能秒杀。
给一个多叉树和一个节点,求出这个节点所有path下来的数字的和。比如给出树和节点
4
4
/ \
2 1
\
3
答案就是413+42 = 455。
这个题倒没什么,拿到就问了他需不需要考虑big int的问题,他说不需要,int肯定够
用。那就放心写了。写完之后我怕有bug在纸上反复写各种test验证。他问我干啥,我
就说我在做“单元测试”。他就让我别在纸上画了直接在collabedit上写。我就把他给
的sample用函数流程走了一遍。。
随后就是一系列的follow up。我一开始给的解不是最优解(犯2了,啥也没想上来先用
了vector存所有路径下的数字,最后我逐个相加)。他也没说什么,因为代码本身没问
题,就是跟我说让我说出时间复杂... 阅读全帖 |
|
d******e 发帖数: 2265 | 26 楼主传的地址没错。错的是指针是copy过去的。改变的是copy后的局部变量。 |
|
S**I 发帖数: 15689 | 27 返回指向局部变量的指针,这个函数压根就是错的嘛。 |
|
o****d 发帖数: 2835 | 28 ids是局部变量 在栈空间中
函数返回就没了
可以用malloc来动态分配这个数组 |
|
s********r 发帖数: 403 | 29 还可以用来加局部变量
不过这些都不是有意思的地方, 找个学过c 的新手,
用 coding standard 好好 training 一个月,就都学会了。
c的好处还是用来设计实时系统,或驱动设备, 什么 I2C, DMA, SCSI,
很多硬件相关协议比我们出生得更早,
而且不能说有权威人士想出了个新的idea, 一拍脑袋,“前面的全不算,把interface
都改掉”,那硬件厂商马上就跳起来了。
这些相对稳定的东西,才是c 程序员饭碗的来源 |
|
a*******n 发帖数: 112 | 30 上周面的,从早9点到晚5点,说好大概一周以内给消息,结果什么消息也没有,是不是
就是婉拒了?也罢,既然没有签什么nondisclosure agreement,我就贡献几道面试题
吧。
- 一个双向链表,带头尾指针,每个节点可能都有父节点和子节点,每个父子节点又是
一个链表。要求把它拍扁,顺序随意。
一开始说了一个类似DFS的算法,他说我的空间复杂度是O(N),我说递归的方法如果堆
栈空间也算的话确实是O(N),但他咬定我临时放节点的地方也是O(N),楞说我存节点需
要分配额外空间,我就很纳闷,这节点都已经是双向链表了,里面有next/prev,为毛
还需要分配O(N)的空间来存这些节点?坚持跟他讨论半天,把节点定义什么都给出来,
一点一点说明白,才证明是他理解有问题,幸好还算坚持,不然就被他带沟里去了。
当然这个算法有更好的解,既然不要求顺序,而且有头尾指针,每次把父子链表接到尾
巴后面就可以了。连递归都省了。
- 算sqrt()
我提出用牛顿法,刚画完坐标系就说不让用。原话是“newton's method is for
mathematics, please use comput... 阅读全帖 |
|
C*G 发帖数: 7495 | 31 我老文科男,野鸡几句,根据中学物理,功耗是物理硬件上的原因。
主要在硬件架构Jazelle和体积上。Java加速,和core共用缓存,ARM寄存器/指针/栈顶
/局部变量可以功能复用,比x86功耗降80%。功耗和温度对应,温度不停升高,功耗更
更高,循环累加;功耗指数形式递增的含温度费米分布参量影响。 |
|
r****y 发帖数: 26819 | 32 03年文青区的大坑?给点提示?
我对大坑一向很无知,基本只逛冷清版,只知道局部变量。请不要对我做假设。 |
|
r****y 发帖数: 26819 | 33 我也忘了很多。只记得作为局部变量,跟小破猫的唯一交集是悉尼奥运会的时候他是奥
运版主,我在他版上灌水。 |
|
r****y 发帖数: 26819 | 34 还好还好,大概可能因为我是局部变量吧,定义域很小。。。 |
|
|
g*******2 发帖数: 1184 | 36 11款用于优化、分析源代码的Java工具
来源:ITeye |
本文将提供一些工具,帮助你优化代码以及检查源代码中的潜在问题。
1. PMD from http://pmd.sourceforge.net/
PMD能够扫描Java 源代码,查找类似以下的潜在问题:
可能的bug——try/catch/finally/switch语句中返回空值。
死代码——未使用的局部变量、参数、私有方法。
不理想的代码——使用String/StringBuffer。
过于复杂的表达式——没有必要使用if语句、while循环可以代替for循环。
重复代码——复制/粘贴的代码引发的bug。
PMD集成了JDeveloper, Eclipse, JEdit, JBuilder, BlueJ, CodeGuide, NetBeans/
Sun Java Studio Enterprise/Creator, IntelliJ IDEA, TextPad, Maven, Ant, Gel,
JCreator, 以及 Emacs。
2. FindBug from http://findbugs.sourceforg... 阅读全帖 |
|
A*******e 发帖数: 2419 | 37 这么用错的厉害。你只能把Array放在堆里。我想声明一个Array类型的局部变量怎么办
?而且可读性很差。
验证一个例子能说明什么问题?楼上用指针才是正解。 |
|
r********g 发帖数: 1351 | 38 buff是函数内局部变量,返回时分配的空间已被系统收回。
你返回的内容没有变只是因为还没有覆盖而已。 |
|
t****t 发帖数: 6806 | 39 return A(c)就不是named RVO了
name的意思就是一个有名字的(局部变量) |
|
s*******t 发帖数: 2896 | 40 这个函数每次进入都会重新分配一次内存吗?
谢谢!
int f()
{
vector key(5000,0);
...
} |
|
|
|
z***e 发帖数: 5393 | 43 int f() {...}
本身每次进入也都会分配内存啊,和f()里头有什么没什么关系吧。 |
|
|
|
q*c 发帖数: 9453 | 46 ..这个对于局部变量 compiler 还是可以check的,看看有没有额外引用就行了。 |
|
q*c 发帖数: 9453 | 47 就是想在局部变量退出 scope 的时候自动化。
但是有了 GC 就不行, 也不知道为什么不设置自动的 destructor。 |
|
x****u 发帖数: 44466 | 48 我是在后面加了个调用,防止x被优化掉。
未被引用局部变量是必被干掉的,所以我的那个例子里面才体现了加volatile与不加的
区别。 |
|
o********n 发帖数: 193 | 49 32位CPU整型一定是4个,连续定义的局部变量地址一定相连。 |
|
N***m 发帖数: 4460 | 50 不是太确定你的意思。还有其他什么情况?
如果只是局部变量没初始化,那我基本可以肯定不是初始化的问题了,
因为编译要求没警告才算通过。 |
|