Убитый процесс SIGKILL - PullRequest
6 голосов
/ 02 января 2012

У меня есть процесс, который убивается сразу после выполнения программы.Это код скомпилированного исполняемого файла, и это небольшая программа, которая считывает несколько графиков, представленных числами, из стандартного ввода (обычно описательный файл) и находит минимальное остовное дерево для каждого графа, используя алгоритм Прима (он не показываетпока результаты, просто найти решение).

#include <stdlib.h>  
#include <iostream>  

using namespace std;

const int MAX_NODOS = 20000;
const int infinito = 10000;

int nnodos;
int nAristas;
int G[MAX_NODOS][MAX_NODOS]; 
int solucion[MAX_NODOS][MAX_NODOS];
int menorCoste[MAX_NODOS];
int masCercano[MAX_NODOS];



void leeGrafo(){
    if (nnodos<0 || nnodos>MAX_NODOS) {
        cerr << "Numero de nodos (" << nnodos << ") no valido\n";
        exit(0);
    }  
    for (int i=0; i<nnodos ; i++)
        for (int j=0; j<nnodos ; j++)
            G[i][j] = infinito; 
    int A,B,P;
    for(int i=0;i<nAristas;i++){
        cin >> A >> B >> P; 
        G[A][B] = P;
        G[B][A] = P;
    }   
}


void prepararEstructuras(){
    // Grafo de salida
    for(int i=0;i<nnodos;i++)
        for(int j=0;j<nnodos;j++)
            solucion[i][j] = infinito;
    // el mas cercaano 
    for(int i=1;i<nnodos;i++){
        masCercano[i]=0;
        // menor coste
        menorCoste[i]=G[0][i];
    }           
}

void prim(){
    prepararEstructuras();
    int min,k;  
    for(int i=1;i<nnodos;i++){
        min = menorCoste[1];
        k = 1;
        for(int j=2;i<nnodos;j++){
            if(menorCoste[j] < min){
                min = menorCoste[j];
                k = j;
            }
        }
        solucion[k][masCercano[k]] = G[k][masCercano[k]];
        menorCoste[k] = infinito;
        for(int j=1;j<nnodos;j++){
            if(G[k][j] < menorCoste[j] && menorCoste[j]!=infinito){
                menorCoste[j] = G[k][j];
                masCercano[j] = k;
            }       
        }           
    }
}

void output(){
    for(int i=0;i<nnodos;i++){
        for(int j=0;j<nnodos;j++)
            cout << G[i][j] << ' ';
        cout << endl;
    }
}

int main (){
    while(true){
        cin >> nnodos;
        cin >> nAristas;
        if((nnodos==0)&&(nAristas==0)) break;
        else{
            leeGrafo();
            output();
            prim(); 
        }
    }   
}

Я узнал, что я должен использовать strace, чтобы найти то, что происходит, и вот что я получаю:

execve("./412", ["./412"], [/* 38 vars */] <unfinished ...>
+++ killed by SIGKILL +++
Killed

Я запускаю Ubuntu, и это первый раз, когда я получаю этот тип ошибок.Предполагается, что программа будет остановлена ​​после чтения двух нулей подряд из входных данных, которые я могу гарантировать, что у меня есть описательный файл моих графиков.Также проблема возникает, даже если я выполняю программу без перенаправления ввода в мой файл графиков.

Ответы [ 2 ]

8 голосов
/ 02 января 2012

Хотя я не уверен на 100%, что это проблема, взгляните на размеры ваших глобальных массивов:

const int MAX_NODOS = 20000;

int G[MAX_NODOS][MAX_NODOS]; 
int solucion[MAX_NODOS][MAX_NODOS];

Предполагая, что int равно 4 байта, вам потребуется:

20000 * 20000 * 4 bytes * 2 = ~3.2 GB

Во-первых, у вас может даже не быть такой большой памяти. Во-вторых, если вы используете 32-разрядную версию, вполне вероятно, что ОС не позволит ни одному процессу иметь столько памяти вообще.

Если вы используете 64-разрядную версию (и если у вас достаточно памяти), решением будет выделить все это во время выполнения.

6 голосов
/ 02 января 2012

Ваши массивы G и solucion содержат по 400 000 000 целых чисел, что составляет около 1,6 ГБ каждый на большинстве компьютеров.Если у вас недостаточно (виртуальной) памяти для этого (3,2 ГБ и счет) и разрешения на ее использование (попробуйте ulimit -d; это правильно для bash в MacOS X 10.7.2), ваш процесс не запустится и будетбыть убитым SIGKILL (который не может быть пойман в ловушку, но процесс еще не завершен).

...