Buonasera a tutti.
Utilizzo Ubuntu per programmare in C, su un portatile con partizione (altro OS Windows7). Premetto che sono alle prime armi con questo linguaggio, tuttavia da alcuni giorni ho riscontrato questo problema a cui non riesco a venire a capo.
Costruendo il programma con una matrice quadrata (es. 10x10) viene eseguito perfettamente, mentre aumentando la dimensione il programma non viene compilato e dal terminale leggo:

(ripetuto per 2 volte)

Stokes.c:(.text+0x3e): rilocazione adattata per troncamento: R_X86_64_PC32 contro il simbolo "dx" definito nella sezione COMMON in /tmp/cc5tjuNC.o

(ripetuto per 1 volta)

Stokes.c:(.text+0x8c): rilocazione adattata per troncamento: R_X86_64_PC32 contro il simbolo "dim" definito nella sezione COMMON in /tmp/cc5tjuNC.o

(ripetuto per 7 volte)

Stokes.c:(.text+0xa2): rilocazione adattata per troncamento: R_X86_64_PC32 contro il simbolo "OFFSET" definito nella sezione COMMON in /tmp/cc5tjuNC.o

(riga finale)

Stokes.c:(.text+0x10f): overflow di rilocazione aggiuntivi omessi dall'output
collect2: error: ld returned 1 exit status

Posto l'ossatura del codice.

// Stokes.c
#include <stdio.h>

#define M 30603
#define N 30603

double dx,dy;
double n;
double L,dim;
int r,c,i,ix,iy,eq,row,col;
double coeff;
double OFFSET[5][3];
double rhs[M];
double A[M][N];

int main() {

L = 1;
n = 100; 
dx = L/n;
dy = dx;

dim = 3*(n+1)*(n+1);

printf("punto1\n");

OFFSET[0][0] = 0; OFFSET[0][1] = 0;        OFFSET[0][2] = 0;
OFFSET[1][0] =-3; OFFSET[1][1] =-3;        OFFSET[1][2] =-1;
OFFSET[2][0] = 2; OFFSET[2][1] = 1;        OFFSET[2][2] =-2;
OFFSET[3][0] = 3; OFFSET[3][1] = 3;        OFFSET[3][2] =-5;
OFFSET[4][0] = 5; OFFSET[4][1] = 3*(n+1); OFFSET[4][2] =-3*(n+1)-1;

printf("punto2\n");

return 0;
}

Grazie a quanti risponderanno.

chiesto 19 Ago '15, 01:29

kolarov19's gravatar image

kolarov19
25114

modificato 19 Ago '15, 10:22

dadexix86's gravatar image

dadexix86 ♦♦
16.9k816161

Mancano alcune informazioni fondamentali.

Con quale compilatore stai compilando e quali parametri gli passi? Versione del compilatore? Versione di Ubuntu?

(19 Ago '15, 10:24) dadexix86 ♦♦ dadexix86's gravatar image

Buonasera a tutti. Riprendendo il programma che stavo realizzando quando ho postato la domanda, mi sono accorto di un problema. In pratica, ho bisogno di trasferire i dati dalla matrice A[N][N] ad una matrice B[N][N+1]. Le quali sono del tutto uguali a meno dell'ultima colonna di B, costituita da un vettore rhs.

for (i=0;i<=(N-1);i++) { for (j=0;j<=(N);j++) { if (j<N) { B[i][j] = A[i][j]; } else { B[i][j] = rhs[i]; } }; };

Non capisco perché la matrice B esca completamente nulla. Ho provato a realizzare la matrice B, come suggeritomi per A, ma il risultato non cambia. Grazie.

(10 Set '15, 11:27) kolarov19 kolarov19's gravatar image

@kolarov19: non usare le risposte per porre altre domande, apri invece una nuova domanda.

(10 Set '15, 23:53) enzotib ♦♦ enzotib's gravatar image

Lo sai che stai allocando una matrice di double (sul mio pc occupa 8B), che in totale richiede uno spazio in memoria maggiore di 7GiB (8 * 30603 * 30603)?

Diminuisci la dimensione e usa un tipo intero (o float, in base a quel che vuoi fare).

EDIT:

Se si ha necessità di usare matrici così grandi, allora lo stack del sistema non è sufficiente (ne puoi controllare la dimensione nel tuo sistema tramite ulimit -s), devi usare lo heap (memoria libera che vedi su free); alloca tramite malloc la matrice:

int **matrice, i;
matrice = malloc(N*sizeof(double*));
for(i=0; i < N; i++)
  matrice[i] = malloc(N*sizeof(double));

con la prima malloc allochi un vettore di puntatori di dimensione N e grandezza di ogni elemento grande quanto un puntatore; nella malloc all'interno del ciclo invece, ad ogni puntatore del vettore allochi un vettore di double, quindi come risultato hai una matrice accessibile tramite i modi che conosci. La malloc non memorizza nello stack ma nello heap, ragion per cui devi usare la free quando non ti serve più quello spazio allocato: basta fare

free(puntatore);

Se vuoi (cosa che, date le grosse dimensioni, conviene fare) puoi controllare il valore di ritorno della malloc per verificare che lo spazio è disponibile al tempo dell'esecuzione.

coll. permanente

ha risposto 19 Ago '15, 10:57

dslul's gravatar image

dslul
9631416

modificato 19 Ago '15, 16:58

@dslul i double sono 64bit l'uno, quindi 8 byte sono corretti :)

Ma il compilatore ritorna errori sulla matrice OFFSET, non sulla A, no?

(19 Ago '15, 11:08) dadexix86 ♦♦ dadexix86's gravatar image

Il problema è proprio quando si deve allocare la matrice A, la OFFSET non sembra che abbia problemi

(19 Ago '15, 11:19) dslul dslul's gravatar image

Buongiorno.

dadaix86, il compilatore che uso è "gcc", mentre la versione corrente e quella di ubuntu sono:

Linux version 3.13.0-46-generic (buildd@orlo) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #79-Ubuntu SMP Tue Mar 10 20:06:50 UTC 2015

Per quanto riguarda dslul sono ben consapevole dell'occupazione della memoria, ma purtroppo non ne posso fare a meno (mi servirebbero anche una matrice più grande, in verità). Tuttavia credo che dslul mi abbia fatto capire il problema: Ubuntu ce l'ho su una partizione da 14 GB, di cui 7(circa) sono già occupati e si trova che i restanti 7(circa) non siano sufficienti per allocare la matrice. Cerco di modificare il seizing della partizione e poi posterò il risultato.

Grazie a coloro che hanno commentato. Buona giornata, a presto.

(19 Ago '15, 12:02) kolarov19 kolarov19's gravatar image

Il problema è la RAM, non lo spazio su disco :)

E per favore a meno di rispondere alla (tua) domanda principale usa i commenti non le risposte, grazie.

(19 Ago '15, 12:05) dadexix86 ♦♦ dadexix86's gravatar image

Scusatemi. Cmq la RAM disponibile è 15.6 GB.

(19 Ago '15, 12:17) kolarov19 kolarov19's gravatar image

Per sicurezza aumenta comunque lo spazio su disco disponibile.

Comunque non mi hai detto quali parametri usi per compilare.

(19 Ago '15, 13:10) dadexix86 ♦♦ dadexix86's gravatar image

Allora lo stack del sistema non è sufficiente (ne puoi controllare la dimensione nel tuo sistema tramite ulimit -s), devi usare lo heap (se non sbaglio corrisponde alla memoria libera che vedi su free); alloca tramite malloc la matrice:

int **matrice, i;
matrice = malloc(N*sizeof(double*));
for(i=0; i < N; i++)
   matrice[i] = malloc(N*sizeof(double));

Se vuoi (cosa che, date le grosse dimensioni, conviene fare) puoi controllare il valore di ritorno della malloc per verificare che lo spazio è disponibile al tempo dell'esecuzione.

(19 Ago '15, 13:52) dslul dslul's gravatar image

dadaix86, scusami: come parametri per la compilazione intendi cosa scrivo nel terminale per compilare il file giusto? In questo caso: gcc nomefile.c -o nomefile ./nomefile

dslul 1)Ecco quanto mi dice il terminale sull'heap (free -m):

         total       used       free     shared    buffers     cached

Mem: 15977 1676 14301 334 67 769 -/+ buffers/cache: 838 15138 Swap: 16308 0 16308

2) ulimit già lo conoscevo e controllato, è settato su "unlimited"

(19 Ago '15, 16:21) kolarov19 kolarov19's gravatar image

3) il codice che mi hai postato mi fa compilare il programma e viene eseguito in toto senza warning. Vorrei sapere se ho capito bene quello che hai fatto:

tramite il ciclo for, ad ogni elemento dell'array [N], corrisponde un array di [N] elementi tipo "double", senza puntatore. La mancanza di "*" nel secondo malloc è giustificata dal fatto che basta il puntatore "al primo elemento dell'array" che in questo caso è il primo elemento di ogni riga della matrice?

Perdonatemi se mi sono spiegato male e vi ringrazio per l'attenzione prestata.

(19 Ago '15, 16:23) kolarov19 kolarov19's gravatar image

con la prima malloc allochi un vettore di puntatori di dimensione N e grandezza di ogni elemento grande quanto un puntatore; nella malloc all'interno del ciclo invece, ad ogni puntatore del vettore allochi un vettore di double, quindi come risultato hai una matrice accessibile tramite i modi che conosci. La malloc non memorizza nello stack ma nello heap, ragion per cui devi usare la free quando non ti serve più quello spazio allocato: basta fare free(puntatore); Modifico la risposta principale in modo da essere più facilmente consultabile. Se hai risolto, accettala come risposta.

(19 Ago '15, 16:53) dslul dslul's gravatar image
La tua risposta
abilita/disabilita anteprima

Segui questa domanda

Via email:

Una volta eseguito l'accesso potrai iscriverti a tutti gli aggiornamenti qui

Via RSS:

Risposte

Risposte e commenti

Basi di markdown

  • *corsivo* o __corsivo__
  • **grassetto** o __grassetto__
  • collegamento:[testo](http://url.com/ "titolo")
  • immagine?![alt testo](/path/img.jpg "titolo")
  • elenco numerato: 1. Foo 2. Bar
  • per aggiungere un'interruzione di riga, aggiungi due spazi a fine riga e premi «Invio»
  • è supportato anche semplice HTML

Tag:

×103
×22
×17

domanda posta: 19 Ago '15, 01:29

domanda visualizzata: 1,564 volte

ultimo aggiornamento: 10 Set '15, 23:53

Chiedi è un servizio di supporto gestito da Ubuntu-it. Contattaci!

powered by OSQAPostgreSQL database
Ubuntu e Canonical sono marchi registrati da Canonical Ltd.