Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在使用共享指针调用的函数中使用此选项是有效的 我有一个关于C++中共享指针和多线程编程的问题。 如果我在线程a中使用此类的共享指针对象调用成员函数, 然后在类中使用this属性并将其传递到回调函数中是有效的,该回调函数将从线程B触发。 从我的角度来看,如果线程A完成了它的工作,那么共享指针将过期,这将是无效的_C++_Shared Ptr - Fatal编程技术网

在使用共享指针调用的函数中使用此选项是有效的 我有一个关于C++中共享指针和多线程编程的问题。 如果我在线程a中使用此类的共享指针对象调用成员函数, 然后在类中使用this属性并将其传递到回调函数中是有效的,该回调函数将从线程B触发。 从我的角度来看,如果线程A完成了它的工作,那么共享指针将过期,这将是无效的

在使用共享指针调用的函数中使用此选项是有效的 我有一个关于C++中共享指针和多线程编程的问题。 如果我在线程a中使用此类的共享指针对象调用成员函数, 然后在类中使用this属性并将其传递到回调函数中是有效的,该回调函数将从线程B触发。 从我的角度来看,如果线程A完成了它的工作,那么共享指针将过期,这将是无效的,c++,shared-ptr,C++,Shared Ptr,是否可以使用来自此的共享\u并将其强制转换为void* 你好,这是密码。这段代码会产生分段错误,对吗 #include <memory> #include <iostream> #include <thread> #include <unistd.h> #include "ClassB.h" class B; class A { public: A()= default; void foo(void * ptr)

是否可以使用来自此的共享\u并将其强制转换为void*

你好,这是密码。这段代码会产生分段错误,对吗

#include <memory>
#include <iostream>
#include <thread>
#include <unistd.h>
#include "ClassB.h"
class B;
class A
{
public:
        A()= default;

        void foo(void * ptr)
        {
            std::cout <<"enter in foo" <<std::endl;
            sleep(1);
            std::cout << "Thread wake up" << std::endl;
            B *pB = reinterpret_cast<B*>(ptr);
            pB->x = 5;
        }
};

void B::bar()
{
    std::cout << "enter in bar" << std::endl;
    void * ptr = reinterpret_cast<void *>(this);
    auto t2= std::thread(&A::foo,A(),ptr);
    t2.detach();
}

void threadTask()
{
    std::cout << "ThreadTask" << std::endl;
    std::shared_ptr<B> psharedB = std::make_shared<B>();
    auto t1 = std::thread(&B::bar,psharedB);
    t1.detach();
}

int main()
{
    auto t = std::thread(threadTask);
    t.join();
    sleep(20);

    return 0;
}
#包括
#包括
#包括
#包括
#包括“B.h类”
乙级;;
甲级
{
公众:
A()=默认值;
无效foo(无效*ptr)
{

std::cout如果对象是在堆上分配的(使用
new
)如果线程完成,它不会变得无效。
shared\u指针
存储一个指向堆上实例的指针和一个指向count变量的指针。如果复制了
shared\u指针
,则count变量会增加,如果调用其析构函数,则会减少。对象的析构函数由共享函数调用如果计数为0,则为d指针,因此如果没有
shared\u指针
s指向对象。
shared\u指针
应为线程保存,即使这是非常占用资源的操作。
shared\u指针
现在负责管理实例,但它不涉及指针的任何其他用法。因此,您不应该对指向该对象的其他指针调用delete。 因此,如果使用
new
分配对象,则不会导致任何冲突

编辑:

这不应该起作用,因为当线程分离并且作用域离开时,
shared_指针
将被销毁,而当
count=1
B
应被销毁时。 拆线总是个坏主意

…文档警告说,在多线程环境中,use_count返回的值是“近似值”,但在这种特殊情况下,它应该是准确的

threadtask
退出时,
psharedB
超出范围。共享指针的析构函数会减少共享指针的使用计数,但是
B
对象实例保持活动状态,因为传递给
t1
线程的
psharedB
副本仍然存在,因此使用计数不是零。

B::bar
中,变量
this
是一个普通的原始
B*
指针。在封盖下面,它是从传递到
t1
线程的智能指针中提取出来的,但就
B::bar
中的逻辑而言,我们不知道这一点。因此,当指针被转换到
void*
时,它就不知道了'根本不影响共享指针的使用计数

探索这一点的一种方法是在
B::bar
中的
reinterpret_cast
上放置一个断点,并运行到该点。断点正下方调用堆栈中的条目将是调用
B::bar
的逻辑以及
psharedB
的副本。调试器应允许您查看共享指针and检查其使用计数,如果
threadTask
已退出,则为1;如果
threadTask
尚未退出,则为2

跨过
重新解释\u cast
,观察共享指针的使用计数没有改变

B::bar
返回时,由
threadTask
启动的
t1
线程终止。实际上,传递给该线程的
psharedB
副本超出范围并被销毁。共享指针使用计数变为零,并且
threadTask
最初创建的
B
对象实例被删除也被摧毁了

此时,传递给
foo
ptr
值是一个指向已删除对象实例的指针。任何试图在
foo
中取消引用该
ptr
值的尝试都将导致未定义的行为。如果幸运的话,它会使程序崩溃。如果不幸的话,取消引用似乎会起作用,并且您会遇到一些困难o跟踪程序执行过程中的后期故障。或某些仅偶尔发生且很难重现的奇怪行为

更糟糕的是,根据
t1
线程被销毁的时间以及
B
对象实例被销毁的时间,
foo
中的变量
ptr
可能是执行部分
foo
的有效
B*
指针,而执行其余
foo
的无效指针


是否可以使用来自此的共享\u并将其强制转换为void*

您的
A
B
类不是从
std::enable\u shared\u from\u this
派生的,因此在您的示例中,在这两个类中调用
std::shared\u都是无效的

如果您确实创建了一个
shared\u ptr
实例,您会发现无法将其强制转换为
void*
。请尝试将
auto temp=reinterpret\u cast(psharedB);
添加到
threadTask
。您会发现编译器错误,因为强制转换无效

在使用共享指针调用的函数中使用它是否有效

是的,它是有效的-在某些限制范围内。从
threadTask
调用的
B::bar
方法是一个使用共享指针调用的函数。您可以在
B::bar
中使用
this
。但是,您不会因为使用共享指针调用
this
而获得任何特殊功能o就
B::bar
而言,它可能是使用这样的原始指针调用的

B* p = new B();
p->bar();
您是否正在使用共享
auto t1 = std::thread(&B::bar, psharedB);
// show use count is two not one
std::cout << "psharedB use count: " << psharedB.use_count() << std::endl;
B* p = new B();
p->bar();