2012-01-02 2 views
6

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

#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(); 
     } 
    } 
} 

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

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

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

+0

Ваша логика программы очень сложна. Что сказал ваш отладчик о ситуации? –

+3

Что-то примечание: ваши массивы с фиксированным размером огромны. При запуске вам понадобится «3,2 ГБ» ... Это может быть проблемой. – Mysticial

+0

@ TomalakGeret'kal: логика программы не имеет значения; ничто из этого не выполняется! – Gabe

ответ

8

Хотя я не 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-разрядном (и предположим, что у вас достаточно памяти), решение было бы выделить все это во время выполнения.

+0

Возможно, это ответ. Я бы предложил изменить эти 'int' массивы на' short', чтобы узнать, помогает ли это. – Gabe

+0

Теперь я вижу, что это проблема, с которой я столкнулся, я просто изменил 2000 на 20, и это работает. Еще один вопрос, пожалуйста, если я хочу продолжать использовать массивы для представления графа без изменения альтернативного списка, могу ли я использовать указатели для int? а не просто int. Решает ли проблема? или мне нужно изменить динамическую структуру? –

+0

Если вы не будете осторожны, указатели просто усугубят проблему, заняв еще больше места. Возможно, у вас недостаточно памяти. Вы на 32-битной или 64-битной машине? Если на 32-битном уровне вы, вероятно, не можете делать проблемы размером 20 000 (потому что общий размер данных слишком близок к 4 GiB). Если вы используете 64-разрядную версию, это зависит от ограничений вашей виртуальной памяти, а не от ограничений, связанных с адресацией процессора. –

6

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

Смежные вопросы