lat*_*des 5 c++ multithreading pointers c++11
我使用std :: thread来执行多个线程.我将指向数组的指针作为参数传递,类似于:
my_type* rest[count];
//Fill rest array
std::thread(fnc, rest, count);
Run Code Online (Sandbox Code Playgroud)
我似乎遇到的问题是,在某个地方,'rest'中的指针值被破坏了.我在调用std :: thread之前打印出指针值,并且std :: thread代表我调用函数中的第一件事,并且值不匹配.它似乎相当随机,有时它们会匹配,有时不匹配(当后者发生时会产生段错误).
我知道(从我在这个主题上找不到的东西)std :: thread复制参数,我认为我的问题源于此,并且有一个特殊的函数std :: ref()允许它传递引用,但没有一个具体提到指针.我尝试过各种技术尝试用std :: ref()传递这个数组,但我还没有解决这个问题.
我是否认为这可能是我的问题的原因,或者我是在咆哮错误的树?
如果以某种方式(数组指针,而不是内容)转换,那么我会遇到问题.
是的,这正是发生的事情.
通常错误地说数组只是指针.问题的真相是每当你声明一个带数组的函数时:
void foo(int x[10]);
Run Code Online (Sandbox Code Playgroud)
声明被'调整',以便参数是一个指针:
void foo(int *x); // C++ can't tell the difference between this and the first declaration
Run Code Online (Sandbox Code Playgroud)
当你调用这个函数时:
int x[10];
foo(x);
Run Code Online (Sandbox Code Playgroud)
有一个隐含的转换,相当于以下内容:
int x[10];
int *tmp = &x[0];
foo(tmp);
Run Code Online (Sandbox Code Playgroud)
所以会发生一个内存块,其中包含指向长寿命对象的指针:
my_type *rest[count] = {new my_type, new my_type, new my_type};
Run Code Online (Sandbox Code Playgroud)
您将指向该内存块的指针传递给该线程:
thread(fnc, &rest[0], count);
Run Code Online (Sandbox Code Playgroud)
然后当函数返回rest超出范围时,该内存块不再有效.
然后线程跟随指向内存块的指针并读取垃圾.如果有可能它确实读取了正确的数组内容,那么它可以很好地访问长寿命对象.问题是从rest过去在堆栈中的损坏的内存块中获取指向长寿命对象的指针.
有没有办法抑制这种行为?
在大多数情况下,唯一有意义的是不使用原始数组作为函数参数.您可以将原始数组包装在结构中并获得合理的行为:
struct int_array {
int x[10];
};
void foo(int_array x);
int main() {
int_array x = {1,2,3,4,5,6,7,8,9,0};
foo(x); // the array is copied rather than getting strangely converted
}
Run Code Online (Sandbox Code Playgroud)
这几乎就是std::array这样,所以你最好使用它.
如果您不想要数组副本,可以引用该数组:
int foo(int (&x)[10]);
Run Code Online (Sandbox Code Playgroud)
这为您提供了与您背后完成的奇怪"调整"和隐式转换基本相同的行为int foo(int x[10]); foo(x);.这里的好处是它是显式的,并且您可以对数组的大小进行类型检查.也就是说,由于'调整',以下不会导致编译器错误:
int foo(int x[10]);
int x[3];
foo(x);
Run Code Online (Sandbox Code Playgroud)
这将:
int foo(int (&x)[10]);
int x[3];
foo(x); // the implicit conversion to &x[0] does not get happen when the function takes a reference to array
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6364 次 |
| 最近记录: |