2012-01-02 14 views
6

Mam proces, który zostaje zabity natychmiast po wykonaniu programu. Jest to kod skompilowanego pliku wykonywalnego, a jest to niewielki program, który odczytuje kilka wykresów reprezentowanych przez liczby ze standardowego wejścia (zwykle jest to plik opisowy) i znajduje minimalne drzewo opinające dla każdego wykresu za pomocą algorytmu Prim (nie pokazuje on wyniki jeszcze, po prostu znaleźć rozwiązanie).Proces zabity przez SIGKILLa

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

dowiedziałem się, że muszę wykorzystać strace aby znaleźć to, co się dzieje, a to, co otrzymuję:

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

ja runiczny ubuntu i jest to pierwszy raz, kiedy się tego typu błędów. Program ma się zatrzymać po przeczytaniu dwóch zera z rzędu, co może zagwarantować, że mam w pliku opisowym wykresy. Również problem występuje, nawet jeśli wykonuję program bez wykonywania przekierowania wejścia do mojego pliku wykresów.

+0

Twoja logika programu jest bardzo trudna do naśladowania. Co Twój debugger powiedział o sytuacji? –

+3

Coś wartego uwagi: Twoje ustalone tablice są ogromne. Podczas uruchamiania będziesz potrzebować> '3,2 GB' ... To może być problem. – Mysticial

+0

@ TomalakGeret'kal: Logika programu nie ma znaczenia; nic z tego nie działa! – Gabe

Odpowiedz

8

Chociaż nie jestem w 100% pewien, że jest to problem, spojrzeć na rozmiary swoich tablic globalnych:

const int MAX_NODOS = 20000; 

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

Zakładając int wynosi 4 bajty, musisz:

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

Po pierwsze, możesz nawet nie mieć tyle pamięci. Po drugie, jeśli korzystasz z 32-bitów, prawdopodobnie system operacyjny nie pozwoli, aby pojedynczy proces miał tak dużo pamięci.

Zakładając, że korzystasz z wersji 64-bitowej (i zakładasz, że masz wystarczającą ilość pamięci), rozwiązaniem byłoby przydzielenie wszystkiego w czasie wykonywania.

+0

To prawdopodobnie odpowiedź. Proponuję zmienić tablice 'int' na' short', żeby zobaczyć, czy to pomaga. – Gabe

+0

Teraz widzę, że to jest problem, który właśnie zmieniłem, zmieniłem tylko 2000 na 20 i działa. Jeszcze jedno pytanie, jeśli chcę nadal używać tablic do reprezentacji wykresu bez zmiany na listę, czy mogę używać wskaźników do int? zamiast tylko int. Czy to rozwiąże problem? czy muszę zmienić na dynamiczną strukturę potrzebną? –

+0

Jeśli nie jesteś ostrożny, wskaźniki po prostu zaostrzają problem, zajmując jeszcze więcej miejsca. Możesz po prostu mieć za mało dostępnej pamięci. Czy korzystasz z komputera 32-bitowego lub 64-bitowego? Jeśli na 32-bitowym, prawdopodobnie nie można zrobić problemów o wielkości 20 000 (ponieważ całkowity rozmiar danych jest zbyt blisko 4 GiB). Jeśli używasz 64-bitów, zależy to od limitów pamięci wirtualnej, a nie od ograniczeń adresowania procesora. –

6

Twoje tablice G i zawierają 400 000 000 liczb całkowitych, co stanowi około 1,6 GiB na większości komputerów. O ile nie masz wystarczającej (wirtualnej) pamięci do tego (3,2 GiB i zliczanie) i uprawnienia do jej używania (spróbuj ulimit -d, to jest poprawne dla bash na MacOS X 10.7.2), twój proces nie powiedzie się i zostanie zabity przez SIGKILL (które nie mogą zostać uwięzione, a proces jeszcze się nie powiódł).

Powiązane problemy