比方说,我有以下代码(纯例):
class a {
int * p;
public:
a() {
p = new int;
}
~a() {
delete p;
}
};
a * returnnew() {
a retval;
return(&retval);
}
int main() {
a * foo = returnnew();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在returnnew()中,在函数返回后(当retval超出范围时)会对retval进行破坏吗?或者它会在我返回地址后禁用自动销毁,我可以说删除foo; 在main()的末尾?或者,以类似的方式(伪代码):
void foo(void* arg) {
bar = (a*)arg;
//do stuff
exit_thread();
}
int main() {
while(true) {
a asdf;
create_thread(foo, (void*)&asdf);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
析构函数会去哪里?在哪里我要说删除?或者这是未定义的行为?唯一可行的解决方案是使用STL引用计数指针吗?这将如何实施?
谢谢 - 我已经使用了C++一段时间但从未遇到过这种情况,并且不想创建内存泄漏.
I'm trying to write some assembly programs using nasm on linux. Everything is good, but I make heavy use of local symbols (.loop, .else, etc.), which is a pain when debugging, because these symbols are emitted to the symbol table, e.g.:
[BITS 32]
global main
section .text
main:
do stuff
.else:
do other stuff
Run Code Online (Sandbox Code Playgroud)
will produce a disassembly that looks like:
<main>:
00000000 do stuff
<main.else>:
00000000 do other stuff
Run Code Online (Sandbox Code Playgroud)
这有点烦人,因为 gdb 会认为这些都是单独的函数,所以当我“disas”时,它只会在遇到另一个标签并停止之前反汇编几条指令。
有没有办法在 linux 下使用 nasm 抑制将这些符号发送到 ELF 符号表?
因此,我正在制作一个素数列表,以帮助我使用简单的试验部门学习haskell(直到我的语言变得更好,没有花哨的东西).我正在尝试使用以下代码:
primes = 2 : [ x | x <- [3..], all (\p -> (mod x p) /= 0) primes]
Run Code Online (Sandbox Code Playgroud)
加载时没有错误.然而:
>take 2 primes
[2ERROR - C stack overflow
Run Code Online (Sandbox Code Playgroud)
我使用嵌套列表推导尝试了同样的事情.它不起作用.我猜我会做太多的递归调用,但如果我只计算一个素数,那就不应该这样了.在我看来,懒惰的评估应该使它做到take 2 primes以下几点:
primes = 2 : [ 3 | all (\p -> (mod 3 p) /= 0) [2] ]
Run Code Online (Sandbox Code Playgroud)
这不需要那么多计算 - mod 3 2 == True所以all (\p -> (mod 3 p) /= 0) == True,这意味着take 2 primes == [2, 3],对吧?我不明白为什么这不起作用.希望有更多精通函数式编程黑魔法的人可以帮助我......
这是在HUGS,如果这有任何区别.
编辑 - …
考虑以下课程:
template <class T>
class defer {
public:
template <class ...Args>
void construct(Args&&...);
T& obj();
~defer();
private:
std::uint8_t memory[sizeof(T)];
T * ptr();
};
template <class T>
template <class ...Args>
void defer<T>::construct(Args&& ...args) {
new(static_cast<void*>(&memory[0])) T(std::forward<Args>(args)...);
}
template <class T>
T& defer<T>::obj() {
return *(ptr());
}
template <class T>
defer<T>::~defer() {
ptr()->~T();
}
template <class T>
T * defer<T>::ptr() {
return static_cast<T*>(&memory[0]);
}
Run Code Online (Sandbox Code Playgroud)
现在我知道这有问题,但为了使代码简短以便讨论,我们假设在对象超出范围之前总是调用defer :: construct().
话虽这么说,这样做总是安全吗?或者可以在一些奇怪的角落中多个虚拟继承与其他疯狂的情况下std :: uint8_t [sizeof(T)]没有分配足够的空间?
说我有以下代码:
template <class Derived>
class Base {
public:
virtual void foo_impl() = 0;
void foo() {
static_cast<Derived*>(this)->foo_impl(); //A
(*static_cast<Derived*>(this)).foo_impl(); //B
}
};
class Derived : public Base<Derived> {
private:
void foo_impl() {
bar();
}
};
Run Code Online (Sandbox Code Playgroud)
几个问题:
A行会生成虚函数调用吗?虽然我在互联网上找到的大部分内容都建议以这种方式做事,但对于我来说,我并没有看到编译器如何进行静态调度,因为指向Derived的指针实际上仍然可以指向Derived2类型的对象,其中Derived2:公共派生.
B行是否解决了我之前提到的问题(如果适用)?考虑到现在调用不再是指针而是因此使用*,它似乎会这样.会避免虚函数调用.但是如果编译器将解除引用的强制转换视为引用类型,它仍然可以生成虚函数调用......在这种情况下,解决方法是什么?
将C++ 11 final关键字添加到foo_impl()会改变编译器在(或任何其他相关)情况下的行为方式吗?
请考虑以下示例代码:
#include <future>
#include <array>
#include <cassert>
typedef std::array<int, 5> foo_t;
foo_t* bar(foo_t& foo) {
return &foo;
}
int main() {
foo_t foo;
auto a = std::async(bar, foo);
auto b = std::async(bar, foo);
assert(a.get() == b.get());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC 4.6.3编译时没有任何投诉.但是,这在运行时失败:
test: test.cpp:15: int main(): Assertion `a.get() == b.get()' failed.
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
但是,GCC 4.8.2拒绝编译该文件:
In file included from /usr/local/include/c++/4.8.2/future:38:0,
from test.cpp:1:
/usr/local/include/c++/4.8.2/functional: In instantiation of 'struct std::_Bind_simple<std::array<int, 5ul>* (*(std::array<int, 5ul>))(std::array<int, 5ul>&)>':
/usr/local/include/c++/4.8.2/future:1525:70: required from 'std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, …Run Code Online (Sandbox Code Playgroud) 我正在编写一个迭代实现Merge Sort的c ++程序.主要代码如下所示,我无法理解为什么我有"访问冲突写入位置0xXXXXXXXX"错误,即使我在另一个程序中以相同的方式分配了更多的内存(1 gb).
void main()
{
//int a[size];
int* a = new int(size); //initialising an int array dynamically contains 16777216 el
srand(time(NULL));
for(int i = 0 ; i < size; i++)
{
a[i]= 1 + rand() % 10;
}
for(int i = 0; (size / 2) / pow((double)2, i)>= 1; i++)
{
int n = pow((double)2, i);
int offset = 0;
for(int j = 0; j < (size / 2) / pow((double)2, i); j++)
{
int* tmp = new …Run Code Online (Sandbox Code Playgroud) 如果我有一个头文件foo.h和一个源文件foo.cpp,并且foo.cpp包含以下内容:
#ifdef WIN32
class asdf {
asdf() { startup_code(); }
~asdf() { cleanup_code(); }
};
asdf __STARTUP_HANDLE__
#else
//unix does not require startup or cleanup code in this case
#endif
Run Code Online (Sandbox Code Playgroud)
但是foo.h没有定义类asdf,比如我有一个应用程序bar.cpp:
#include "foo.h"
//link in foo.lib, foo.dll, foo.so, etc
int main() {
//do stuff
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果bar.cpp是在WIN32平台上编译的,那么asdf()和~asdf()会在适当的时候(分别在main()之前和程序退出时)调用,即使在foo.h中没有定义类asdf也是如此. ,但通过foo.cpp链接?