忽发其想
时间:2014-03-01
来源:互联网
C++11提供左lambda功能
也提供左std::function....用来把function物件化
但问题来了
lambda最大特徵就系外部变数引用...
如果....外部变数被毁灭左.....到底C++11的lambda会发生甚么事..??
当然...如果系pass by value就冇咩问题...
但pass by pointer/reference的话问题就大了....更何况大量使用pointer/reference才是C++的本色
以下code例子
VC++ 2012的debug和release mode会有不同结果
release mode的话...外部变数还生存...而且还"正确地"显示出记忆体位置和做两次operator ++....并显示出答案"1"和"2"
而foo2的i...原本谂住在相同的function开端结构的话...在stack上会建立出相同的资料结构...
所以想试试覆写掉stack上的记忆体...结果不成功
[ 本帖最后由 Susan﹏汪汪 於 2014-2-17 01:34 AM 编辑 ]
也提供左std::function....用来把function物件化
但问题来了
lambda最大特徵就系外部变数引用...
如果....外部变数被毁灭左.....到底C++11的lambda会发生甚么事..??
当然...如果系pass by value就冇咩问题...
但pass by pointer/reference的话问题就大了....更何况大量使用pointer/reference才是C++的本色
以下code例子
VC++ 2012的debug和release mode会有不同结果
复制内容到剪贴板代码:function<int()> foo(function<int()> dummy)
{
int i = 0;
cout << "&i: " << &i << endl;
function<int()> result = [&]()
{
++i;
cout << "&i: " << &i << endl;
return i;
};
return result;
}
function<int()> foo2(function<int()> outer)
{
int i = 5;
cout << "&i: " << &i << endl;
cout << "i: " << outer() << endl;
return outer;
}
void main()
{
system("color 0a");
int a = 0;
cout << "&a: " << &a << endl;
function<int()> dummy;
auto functor = foo(dummy);
cout << "i: " << functor() << endl;
foo2(functor);
while(true);
}
debug mode的话...外部变数被毁灭...但第二次写入动作才弹出error{
int i = 0;
cout << "&i: " << &i << endl;
function<int()> result = [&]()
{
++i;
cout << "&i: " << &i << endl;
return i;
};
return result;
}
function<int()> foo2(function<int()> outer)
{
int i = 5;
cout << "&i: " << &i << endl;
cout << "i: " << outer() << endl;
return outer;
}
void main()
{
system("color 0a");
int a = 0;
cout << "&a: " << &a << endl;
function<int()> dummy;
auto functor = foo(dummy);
cout << "i: " << functor() << endl;
foo2(functor);
while(true);
}
release mode的话...外部变数还生存...而且还"正确地"显示出记忆体位置和做两次operator ++....并显示出答案"1"和"2"
而foo2的i...原本谂住在相同的function开端结构的话...在stack上会建立出相同的资料结构...
所以想试试覆写掉stack上的记忆体...结果不成功
[ 本帖最后由 Susan﹏汪汪 於 2014-2-17 01:34 AM 编辑 ]
作者: Susan﹏汪汪 发布时间: 2014-03-01
如果要解释的话....debug mode的系正确运行程式
而release mode系部分正确的运行程式
首先...当foo做左return后...变数i即时被毁灭
所以所占用的记忆体应该已归还给系统
而debug mode就在第二次写入动作才侦测到error (OMG)
但release mode的话....
它没有毁灭变数i...还留在使用理应系VC++的大错处
但不要忘掉C++系有inline function
即系话foo本身已经做了inline处理...而变数i其实已经系main的变数
那么就表示...程式只是正确地读取/写入main的变数i而已
而release mode系部分正确的运行程式
首先...当foo做左return后...变数i即时被毁灭
所以所占用的记忆体应该已归还给系统
而debug mode就在第二次写入动作才侦测到error (OMG)
但release mode的话....
它没有毁灭变数i...还留在使用理应系VC++的大错处
但不要忘掉C++系有inline function
即系话foo本身已经做了inline处理...而变数i其实已经系main的变数
那么就表示...程式只是正确地读取/写入main的变数i而已
作者: Susan﹏汪汪 发布时间: 2014-03-01
另外....
最近因为外面有人做闹钟
汪汪就去研究过关於平行运算...和timer的问题...
发现原来window的timer api出奇地易用(当然以所有参数都使用预设值作大前提)
汪汪把丑陋的window timer api包装了一个class...然后再使用
不过还有个问题....
就是...因为window的timer并没有排队的观念...时间一到就马上create新thread
所以如果当timer create一个thread后....个thread运算过长时间...
在不停create新thread的情况下就变成大混乱
所以汪汪还不知道....系咪应该加一些控制...例如加锁防止data race
但是未在前thread结束...就已经不停create新thread的问题还是不能控制
最近因为外面有人做闹钟
汪汪就去研究过关於平行运算...和timer的问题...
发现原来window的timer api出奇地易用(当然以所有参数都使用预设值作大前提)
汪汪把丑陋的window timer api包装了一个class...然后再使用

不过还有个问题....
就是...因为window的timer并没有排队的观念...时间一到就马上create新thread
所以如果当timer create一个thread后....个thread运算过长时间...
在不停create新thread的情况下就变成大混乱
所以汪汪还不知道....系咪应该加一些控制...例如加锁防止data race
但是未在前thread结束...就已经不停create新thread的问题还是不能控制
复制内容到剪贴板代码:string placeValueNotation(uintmax_t x, uintmax_t n)
{
const char list[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string result;
if(x == 0) return "0";
while(x)
{
result = list[x % n] + result;
x /= n;
}
return result;
}
void main()
{
system("color 0a");
default_random_engine generator;
auto GetRandom = bind(uniform_int_distribution<uintmax_t>(0, 9999999999999999999), std::ref(generator));
uintmax_t count = 0, fps = 10;
timer timer([&]()
{
system("cls");
cout << placeValueNotation(GetRandom(), 16) << endl;
cout << count / fps << '.' << count % fps << endl;
++count;
}, 0, 1000 / fps);
while(true);
}
{
const char list[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string result;
if(x == 0) return "0";
while(x)
{
result = list[x % n] + result;
x /= n;
}
return result;
}
void main()
{
system("color 0a");
default_random_engine generator;
auto GetRandom = bind(uniform_int_distribution<uintmax_t>(0, 9999999999999999999), std::ref(generator));
uintmax_t count = 0, fps = 10;
timer timer([&]()
{
system("cls");
cout << placeValueNotation(GetRandom(), 16) << endl;
cout << count / fps << '.' << count % fps << endl;
++count;
}, 0, 1000 / fps);
while(true);
}
作者: Susan﹏汪汪 发布时间: 2014-03-01
我用 GCC 4.8.1,无用同有用优化(-O2),结果亦都不一样。前者显示 i 嘅值,依次为 0 同 6;而后者两次都系 1。
得到唔同结果,正正表示你咁嘅用法,行为不被定义。
以下系讲解 lambda 用法网页(网址:http://www.cprogramming.com/c++11/c++11-lambda-closures.html)其中一段:
得到唔同结果,正正表示你咁嘅用法,行为不被定义。
以下系讲解 lambda 用法网页(网址:http://www.cprogramming.com/c++11/c++11-lambda-closures.html)其中一段:
引用:When you capture by reference, the lambda function is capable of modifying the local variable outside the lambda function--it is, after all, a reference. But this also means that if you return a lamba function from a function, you shouldn't use capture-by-reference because the reference will not be valid after the function returns.
C/C++ 有好多地方,规格讲明系行为不被定义。正如好多人都知,唔可以将函数内嘅区域变数嘅地址传回,然后取或赋值一样:
复制内容到剪贴板代码:int* foo() {
int i = 0;
return &i;
}
int bar() {
int j = 99;
return j;
}
int mai() {
int *pi = foo();
cout << *pi << endl;
bar();
++(*pi);
cout << *pi << endl;
}
int i = 0;
return &i;
}
int bar() {
int j = 99;
return j;
}
int mai() {
int *pi = foo();
cout << *pi << endl;
bar();
++(*pi);
cout << *pi << endl;
}
作者: fitcat07 发布时间: 2014-03-01
引用:原帖由 Susan﹏汪汪 於 2014-2-17 03:50 AM 发表
另外....
最近因为外面有人做闹钟
汪汪就去研究过关於平行运算...和timer的问题...
发现原来window的timer api出奇地易用(当然以所有参数都使用预设值作大前提)
汪汪把丑陋的window timer api包装了一个class. ...
原来Window timer API有个flag....正正系汪汪想要的处理data race方法的效果 另外....
最近因为外面有人做闹钟
汪汪就去研究过关於平行运算...和timer的问题...
发现原来window的timer api出奇地易用(当然以所有参数都使用预设值作大前提)
汪汪把丑陋的window timer api包装了一个class. ...
作者: Susan﹏汪汪 发布时间: 2014-03-01
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28