(openmp) 我得到了奇怪的字符串,"r_saving"
(openmp) I get strange string, "r_saving"
我练习使用 OpenMP,为此,我制作了一个非常简单的并行打印程序。
我有一个 2d char*
数组,我用以下函数填充它:
void addItem( char * arr[4][4], int row, int col ) {
for ( int i=0; i< row; i++ ) {
for ( int j=0; j< col; j++ ) {
arr[i][j] = new char [10];
strcpy( arr[i][j], "input");
char * tmp = new char [5];
*tmp = ( i + '0' );
strcat( arr[i][j],tmp );
delete [] tmp;
}
}
}
在我的主要功能中,我有以下内容:
int threadNum =4;
omp_set_num_threads(threadNum);
#pragma omp parallel
{
#pragma omp for
for ( int i=0; i<threadNum; i++ ) {
cout << omp_get_thread_num() << endl;
#pragma omp critical
{
printItem ( input, row, col );
}
}
}
printItem()
函数的作用是打印数组的元素
void printItem (char * arr[4][4], int row, int col) {
for ( int i=0; i<row; i++ ) {
cout << " row " << i << endl;
for ( int j=0; j<col; j++ ) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
输出为
01
row 0
input0 input0 input0 input0
row 1
input1 input1 input1 input1r_savings
row 2
input2 input2 input2 input2
row 3
input3 input3 input3 input3
32
row 0
input0 input0 input0 input0
row 1
input1 input1 input1 input1r_savings
row 2
input2 input2 input2 input2
row 3
input3 input3 input3 input3
.......
如您所见,在每个线程的作业中,都有 "r_savings" 我没有在函数中的任何地方添加。
你能告诉我这是从哪里来的吗?
我做错了什么吗?
您的问题与 OpenMP 或并行性无关,而与 C 字符串及其终止符有关。
在下面的代码中
arr[i][j] = new char [10];
strcpy( arr[i][j], "input");
char * tmp = new char [5];
*tmp = ( i + '0' );
strcat( arr[i][j],tmp );
delete [] tmp;
- 你分配一个10个字符的字符串,然后你在里面复制
"input"
。您的字符串现在是 { 'i', 'n', 'p', 'u', 't', '[=13=]', ... }
(据我所知,最后 4 个元素具有未定义的值)。
- 然后分配一个 5 个字符的字符串
tmp
,将第一个元素设置为与索引 i
的值相对应的字符。 tmp
现在是(例如 i
等于零){ '0', ... }
.
- 您是否注意到
tmp
字符串没有 NULL
终止符?那么这就是问题的原因。因为现在,当您使用 tmp
作为第二个参数调用 strcat()
时,该函数不知道在哪里停止复制。更具体地说,该函数将继续复制,直到它在 tmp
指向的内存中找到一个 NULL
字符,这可能需要一段时间,并以糟糕的方式结束。
我会根据您选择的样式快速修复您的代码,但由于您使用的是 C++,我强烈建议您使用 std::string
而不是 char*
来处理字符串。
所以这应该 "fix" 这部分代码:
arr[i][j] = new char[10];
sprintf( arr[i][j], "input%d", i );
我练习使用 OpenMP,为此,我制作了一个非常简单的并行打印程序。
我有一个 2d char*
数组,我用以下函数填充它:
void addItem( char * arr[4][4], int row, int col ) {
for ( int i=0; i< row; i++ ) {
for ( int j=0; j< col; j++ ) {
arr[i][j] = new char [10];
strcpy( arr[i][j], "input");
char * tmp = new char [5];
*tmp = ( i + '0' );
strcat( arr[i][j],tmp );
delete [] tmp;
}
}
}
在我的主要功能中,我有以下内容:
int threadNum =4;
omp_set_num_threads(threadNum);
#pragma omp parallel
{
#pragma omp for
for ( int i=0; i<threadNum; i++ ) {
cout << omp_get_thread_num() << endl;
#pragma omp critical
{
printItem ( input, row, col );
}
}
}
printItem()
函数的作用是打印数组的元素
void printItem (char * arr[4][4], int row, int col) {
for ( int i=0; i<row; i++ ) {
cout << " row " << i << endl;
for ( int j=0; j<col; j++ ) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
输出为
01
row 0
input0 input0 input0 input0
row 1
input1 input1 input1 input1r_savings
row 2
input2 input2 input2 input2
row 3
input3 input3 input3 input3
32
row 0
input0 input0 input0 input0
row 1
input1 input1 input1 input1r_savings
row 2
input2 input2 input2 input2
row 3
input3 input3 input3 input3
.......
如您所见,在每个线程的作业中,都有 "r_savings" 我没有在函数中的任何地方添加。
你能告诉我这是从哪里来的吗? 我做错了什么吗?
您的问题与 OpenMP 或并行性无关,而与 C 字符串及其终止符有关。
在下面的代码中
arr[i][j] = new char [10];
strcpy( arr[i][j], "input");
char * tmp = new char [5];
*tmp = ( i + '0' );
strcat( arr[i][j],tmp );
delete [] tmp;
- 你分配一个10个字符的字符串,然后你在里面复制
"input"
。您的字符串现在是{ 'i', 'n', 'p', 'u', 't', '[=13=]', ... }
(据我所知,最后 4 个元素具有未定义的值)。 - 然后分配一个 5 个字符的字符串
tmp
,将第一个元素设置为与索引i
的值相对应的字符。tmp
现在是(例如i
等于零){ '0', ... }
. - 您是否注意到
tmp
字符串没有NULL
终止符?那么这就是问题的原因。因为现在,当您使用tmp
作为第二个参数调用strcat()
时,该函数不知道在哪里停止复制。更具体地说,该函数将继续复制,直到它在tmp
指向的内存中找到一个NULL
字符,这可能需要一段时间,并以糟糕的方式结束。
我会根据您选择的样式快速修复您的代码,但由于您使用的是 C++,我强烈建议您使用 std::string
而不是 char*
来处理字符串。
所以这应该 "fix" 这部分代码:
arr[i][j] = new char[10];
sprintf( arr[i][j], "input%d", i );