C++ 函数中初始化局部变量和运行语句的顺序是什么(+;内存顺序)?
对于下面的代码,Lock对象是在第一条语句之后还是之前初始化的C++ 函数中初始化局部变量和运行语句的顺序是什么(+;内存顺序)?,c++,variables,memory-model,C++,Variables,Memory Model,对于下面的代码,Lock对象是在第一条语句之后还是之前初始化的 int* data = NULL; int* example() { if (data) return data; Lock lock; data = new int[10]; return data; } 我知道它应该按照预期的方式工作: int* data = NULL; int* example() { if (data) return data; { Lock lock; if
int* data = NULL;
int* example() {
if (data) return data;
Lock lock;
data = new int[10];
return data;
}
我知道它应该按照预期的方式工作:
int* data = NULL;
int* example() {
if (data) return data;
{
Lock lock;
if (!data)
data = new int[10];
}
return data;
}
但上述两种方法是否都适用于弱内存顺序机器上的多线程?我试图搜索,但找不到答案。当执行通过局部变量的定义点时,局部变量被初始化。也就是说,您的
example()
的第一个实现相当于(这甚至不正确地使用了双重检查锁定-除了数据竞争之外,它省略了第二个检查…):
假设您的代码>锁类获得适当初始化的互斥体,代码仍有一个数据竞争,根据C++标准:在<代码> > <代码> >语句和<代码>返回< /代码>语句中,与设置<代码>数据< /代码>不同步。因此,所有这些功能都会导致根据C++标准的未定义行为。避免所有问题的一个简单解决方法是依赖于初始化函数localstatic
变量的保证:
int* example() {
static int* rc = new int[10];
return rc;
}
必须以线程安全的方式初始化
rc
。如果多个线程同时尝试初始化rc
,则只有一个线程能够这样做,而所有其他线程都被阻塞,直到初始化完成。避免NULL
并改用NULL ptr
(c++11)。避免返回动态创建的内存。改用RIII。最后你有一个内存泄漏,你的void函数不返回一个指针,所以你可以;t在函数执行后不进行处理,实际上按照C++标准:读取<代码>数据< /代码>具有初始化“代码>数据< /代码>的数据竞争,导致未定义行为。只需使用int*example(){static int*rc=new int[10];返回rc;}
谢谢您的回答。您能解释一下关于“读取if语句中的数据,并且返回语句稍后与设置数据不同步”的更多信息吗?@user3701366:语句if(data)
读取数据的值。此时,没有同步(例如,锁或数据是原子的)。但另一个线程可能会写入数据
。写入使用锁,但由于读取不同步,因此读取和写入之间仍然存在数据竞争。
int* example() {
static int* rc = new int[10];
return rc;
}