2016-06-08 90 views
0

我正在嘗試使用MPI創建服務器的某些內容,並且我可以將其編譯,但是當我運行它時,它會馬上發生故障。我試圖添加打印語句來查看它崩潰的位置,但這沒有幫助。我是使用MPI的新手,但無法找到問題所在。我正在使用Mac,我試圖找出llvm,因爲我無法使用GDB檢查覈心轉儲,因此在此期間的任何幫助都非常感謝。C++ MPI代碼在運行時出現故障11

#include "mpi.h" 
#include <iostream> 
#include <list> 
using namespace std; 

void error(const char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 

int main(int argc, char **argv) 
{ 
    int MAX_DATA = 255; 
    MPI_Comm client; 
    MPI_Status status; 
    char port_name[MPI_MAX_PORT_NAME]; 
    int size, again; 
    double buf[MAX_DATA]; 
    cout << "Did we get here? [1]"; 
    MPI_Init(NULL, NULL); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    cout << "Did we get here before it pukes"; 
    if (size != 1) error("ERROR"); 

    // Create the random list 
    list<int> rand_list; 
    list<int>::iterator it; 
    for(int i = 0; i < 5; ++i) 
    { 
     int r; 
     r = rand(); 
     rand_list.insert (it,r); 
     it++; 
    } 

    cout << "mylist contains:"; 
    for (it=rand_list.begin(); it!=rand_list.end(); ++it) 
    { 
     cout << ' ' << *it; 
     cout << '\n'; 
    } 

    MPI_Open_port(MPI_INFO_NULL, port_name); 
    printf("server available at %s\n",port_name); 
    while (1) { 
     MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &client); 
    again = 1; 
    while (again) { 
     MPI_Recv(buf, MAX_DATA, MPI_DOUBLE, 
        MPI_ANY_SOURCE, MPI_ANY_TAG, client, &status); 
     switch (status.MPI_TAG) { 
      case 0: MPI_Comm_free(&client); 
        MPI_Close_port(port_name); 
        MPI_Finalize(); 
        return 0; 
      case 1: MPI_Comm_disconnect(&client); 
        again = 0; 
        break; 
      case 2: /* do something */ 
       cout << "Why did we get here?"; 
      default: 
        /* Unexpected message type */ 
        MPI_Abort(MPI_COMM_WORLD, 1); 
      } 
     } 
     } 
} 

[asdfa:04443] *** Process received signal *** 
[asdfa:04443] Signal: Segmentation fault: 11 (11) 
[asdfa:04443] Signal code: Address not mapped (1) 
[asdfa:04443] Failing at address: 0x0 
[asdfa:04443] [ 0] 0 libsystem_platform.dylib   0x00007fff8ed1452a _sigtramp + 26 
[asdfa:04443] [ 1] 0 ???         0x0000000000000001 0x0 + 1 
[asdfa:04443] [ 2] 0 server.o       0x000000010a40eba2 main + 834 
[asdfa:04443] [ 3] 0 libdyld.dylib      0x00007fff9cb245ad start + 1 
[asdfa:04443] *** End of error message *** 
Segmentation fault: 11 (core dumped) 
+0

您可能會添加您用於編譯和運行的命令.... –

+0

這裏,在linux和gcc下,它在第一次調用'rand_list.insert(it,r)時失敗了;' –

+0

爲什麼不能你使用'gdb'來檢查覈心轉儲? –

回答

0

您的問題是位於這行代碼:

list<int>::iterator it; 
for(int i = 0; i < 5; ++i) 
{ 
    int r; 
    r = rand(); 
    rand_list.insert (it,r); 
    it++; 
} 

有兩個問題:

  • 你聲明的迭代器,但你永遠不指定一個有效的值對它來說,它指向任何地方。但迭代器必須指向列表中的有效位置。無論rand_list.begin()rand_list.end()是合法的,所以你需要:

    list<int>::iterator it = rand_list.end();

  • 然後第一個參數是您插入元素的位置。在迭代器指向的位置之前插入新元素。因此,無論您最初選擇begin()還是end()作爲迭代器(它們對於空列表都是相同的),通過遞增它,您會將其增加到列表末尾,這是未定義的行爲。只需在最後總是插入:

    rand_list.insert (rand_list.end(), r);

但是你爲什麼不乾脆用push_back(或push_front,如果你喜歡)?