MPI_send和MPI_receive字符串

时间:2015-02-07 07:56:34

标签: c++ mpi

我已经阅读了很多页面,但我无法找到解决问题的方法:我必须将3个整数的数组从根进程传递到工作进程,其中:

  • first int是每个进程要验证的页数
  • 第二个int是开始验证的ID
  • 第三个int是要在该页面中搜索的字符串的长度。

发送此数组后,我发送要搜索的字符串。问题在于接收:发送字符串的长度是正确的,但是当我输出字符串时我有这个:例如,如果我发送“sport”,在输出上我有“sport222 |||”。这是代码:

int main(int argc, char *argv[]){
     int rank;
     int noOfProcs;
     string stringToBeSearched = "";
     int root_process;
     int ierr;
     int avgPerProcess;
     int totalNoOfPages;
     int noOfPagesForLastProc;
     int proc;
     char* receivedString = "";
     int receivedSLen;
     int dataToSend[3];
     int receivedData[3];
     vector<HtmlPage> pages;
     char* s = "";
     clock_t tStart;
     MPI_Status status;

     ierr = MPI_Init(&argc, &argv);
     root_process = 0;
     ierr = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
     ierr = MPI_Comm_size(MPI_COMM_WORLD, &noOfProcs);

     if (rank == root_process) {
        cout << "Enter text: ";
        getline(cin, stringToBeSearched);
        //calculate the number of pages to be verified by each process
        totalNoOfPages = getTotalNumberOfPages();
        avgPerProcess = totalNoOfPages / noOfProcs;
        //send the array to each process
        noOfPagesForLastProc = avgPerProcess + (totalNoOfPages % noOfProcs);
        for (proc = 1; proc < noOfProcs; proc++) {
            dataToSend[0] = avgPerProcess;
            dataToSend[1] = proc * avgPerProcess;   
            dataToSend[2] = stringToBeSearched.size();
            if (proc == noOfProcs - 1){
                dataToSend[0] = noOfPagesForLastProc;
            }
            ierr = MPI_Send(&dataToSend[0], 3, MPI_INT,
               proc, send_data_tag, MPI_COMM_WORLD);            
            //send the string to be searched
            ierr = MPI_Send(stringToBeSearched.c_str(), stringToBeSearched.size(), MPI_CHAR, proc, send_data_tag, MPI_COMM_WORLD);
        }
        //verify pages in the segment assigned
        //to the root process
        //get the pages assigned

        pages = getPagesForProcess(avgPerProcess, 0);
        for (int i = 0; i < pages.size(); i++) {
            string searched = pages[i].getContent();
            const char* ch = searched.c_str();
            if (strstr(ch, s) != NULL){
               cout << "Process 0" << " founded matches at: " << endl;
               cout << pages[i].getUrl() << endl;
            }
        }
    }
    else {
        //worker process receive the array segment,
        //storing it in a "local" array
        ierr = MPI_Recv(&receivedData[0], 3, MPI_INT,
        root_process, send_data_tag, MPI_COMM_WORLD, &status);
        receivedSLen = receivedData[2];     
        receivedString = new char[receivedSLen];
        ierr = MPI_Recv(receivedString, receivedSLen, MPI_CHAR, root_process, send_data_tag, MPI_COMM_WORLD, &status);
        //this line of code outputs the "bad" string
        cout << "received string = " << receivedString << endl;

        //get the assigned pages to verify
        pages = getPagesForProcess(receivedData[0], receivedData[1]);
        for (int i = 0; i < pages.size(); i++) {
            string searched = pages[i].getContent();
            const char* ch = searched.c_str();
            if (strstr(ch, receivedString) != NULL){
                cout << "Process " << rank << " founded matches at: " << endl;
                cout << pages[i].getUrl() << endl;
            }
            else {
                cout << "No matches founded by process " << rank << endl;
            }
       }    
    }
    cout << "Time taken for execution " << (double)(clock() - tStart) / CLOCKS_PER_SEC << " s." << endl;
    ierr = MPI_Finalize();
    _getch();
    return 0;
}

1 个答案:

答案 0 :(得分:2)

问题是你的字符串缺少空终止符。

 receivedString = new char[receivedSLen];

应该是:

 receivedString = new char[receivedSLen + 1]();

这为终止null分配了1个字符,并且还将数据初始化为默认值(无论如何都是0)。

更好的是,使用std::vector

消除内存泄漏
 std::vector<char> receivedString(receivedSLen + 1,0);
 cout << "received string = " << &receivedString[0] << endl;

您应该考虑的问题是字符串是否可以包含嵌入的NULL个字符。如果是这样,那么你必须使用不同的方法来处理字符串,因为你现在使用的函数现在依赖于终止\0

在这种情况下,数据可能已嵌入NULL s,

cout << "received string = ";
cout.write(receivedString, receivedSLen);
cout << endl;

如果使用std::vector

cout << "received string = ";
cout.write(&receivedString[0], receivedSLen);
cout << endl;