|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Mar 2005
Messaggi: 1653
|
[C] Dimensione array definita dinamicamente
Salve ragazzi!
Sto riprendendo il linguaggio C a distanza di oltre un anno, ed improvvisamente mi è crollata una certezza Per quanto ne so, quando si definisce un array la sua dimensione deve essere nota in fase di compilazione, ed in particolare essa deve essere una costante. Ora, facendo un po' di prove, mi accorgo che compilando ed eseguendo un programma del genere: Codice:
#include <stdio.h>
int main(void)
{
int c;
int DIM;
printf("Inserisci dimensione array: ");
scanf("%d", &DIM);
int stringa[DIM];
for (c = 0; c < DIM; c++)
stringa[c] = c;
printf("\nFine\n");
return 0;
}
Qualcuno saprebbe spiegarmi come mai? Preciso che uso gcc versione 4.2.4 su Linux 2.6.24 64 bit
__________________
gica78r@ncc-1701:~$ tar -c tar: Codardamente mi rifiuto di creare un archivio vuoto |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Apr 2006
Messaggi: 22462
|
per il c99 si può fare, è il c++ che non lo supporta
__________________
amd a64x2 4400+ sk939;asus a8n-sli; 2x1gb ddr400; x850 crossfire; 2 x western digital abys 320gb|| asus g1
Se striscia fulmina, se svolazza l'ammazza |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Mar 2005
Messaggi: 1653
|
Ho provato anche a compilare questo con g++, e non ricevo errori nemmeno a runtime...
Codice:
#include <iostream>
using namespace std;
int main(void)
{
int d;
cout << "Inserisci dimensione array: ";
cin >> d;
int vettore[d];
for (int i = 0; i < d-1; i++)
vettore[i] = i;
cout << "Fatto!"<<endl;
return 0;
}
EDIT: solo se compilo passando a gcc l'opzione -pedantic ricevo il warning sulla dimensione variabile dell'array, ma non un errore... Quote:
__________________
gica78r@ncc-1701:~$ tar -c tar: Codardamente mi rifiuto di creare un archivio vuoto Ultima modifica di Gica78R : 27-01-2009 alle 15:05. |
|
|
|
|
|
|
#4 | |
|
Senior Member
Iscritto dal: Apr 2006
Messaggi: 22462
|
Quote:
__________________
amd a64x2 4400+ sk939;asus a8n-sli; 2x1gb ddr400; x850 crossfire; 2 x western digital abys 320gb|| asus g1
Se striscia fulmina, se svolazza l'ammazza |
|
|
|
|
|
|
#5 | |
|
Member
Iscritto dal: Jan 2009
Messaggi: 30
|
Quote:
se vuoi inizializzare un array puoi ovviamente farlo durante il programma, ma la dimensione (la dimensione MASSIMA) deve essere definita in modo statico, magari con un #define il tuo frammento di codice io lo farei cosi: Codice:
#include <stdio.h>
#include <stdlib.h>
#define MAXDIM 128
int main(void)
{
int c, dim;
int stringa[MAXDIM];
printf("Inserisci dimensione array: ");
scanf("%d", &dim);
for (c = 0; c < dim; c++)
stringa[c] = c;
printf("\nFine\n");
return EXIT_SUCCESS;
}
|
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Mar 2005
Messaggi: 1653
|
Anch'io lo farei così, e l'ho sempre fatto così!
Però la mia era una curiosità, scaturita dopo aver letto questa frase su un libro di Kernighan e Pike del 1999 (The practice of programming) a proposito delle differenze tra C e C++: Quote:
Ora mi chiedo: il fatto che lo standard C99 permetta una cosa del genere, implica anche che sia corretto? Ovvero, posso istanziare array usando per dimensione una variabile senza preoccuparmi delle conseguenze a runtime o, pur essendo consentito dallo standard, la cosa rimane sbagliata? ![]() Grazie
__________________
gica78r@ncc-1701:~$ tar -c tar: Codardamente mi rifiuto di creare un archivio vuoto |
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Dipende tutto da chi deve guardare quel codice...se è un professore, mediamente poco informato sugli standard "nuovi", usa l'allocazione dinamica. Altrimenti puoi fare quello che vuoi...quello è C standard
In C++ ad esempio non lo farei. |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Apr 2006
Messaggi: 22462
|
hai detto bene, mediamente. i professori che conosco io sono sempre stati i primi ad aggiornarsi ai nuovi standard
__________________
amd a64x2 4400+ sk939;asus a8n-sli; 2x1gb ddr400; x850 crossfire; 2 x western digital abys 320gb|| asus g1
Se striscia fulmina, se svolazza l'ammazza |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Mar 2005
Messaggi: 1653
|
Quote:
![]() A questo punto credo che usare lo standard C90 può essere utile solo per compatibilità con compilatori più vecchi, no?
__________________
gica78r@ncc-1701:~$ tar -c tar: Codardamente mi rifiuto di creare un archivio vuoto Ultima modifica di Gica78R : 27-01-2009 alle 21:45. |
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Apr 2006
Messaggi: 22462
|
visto che la borland si ostina a distribuire un compilatore che non supporta nemmeno le costanti nelle classi, figurati questi "dettagli"
__________________
amd a64x2 4400+ sk939;asus a8n-sli; 2x1gb ddr400; x850 crossfire; 2 x western digital abys 320gb|| asus g1
Se striscia fulmina, se svolazza l'ammazza |
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
|
|
|
|
|
|
#13 |
|
Senior Member
Iscritto dal: Mar 2005
Messaggi: 1653
|
Beh, non dovrei aver bisogno di compilatori (o sistemi operativi, o applicazioni) Microsoft, almeno per i prossimi 150 anni
__________________
gica78r@ncc-1701:~$ tar -c tar: Codardamente mi rifiuto di creare un archivio vuoto |
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
bah, banalissimo: l'allocazione di un vettore in memoria automatica avviene sottraendo una determinata quantitá allo stack pointer; la semantica che tu riporti (dichiarazione di un array con una variabile come dimensione anziché una costante) fa si' che il codice generato dal compilatore sottragga allo stack pointer il valore contenuto in una certa variabile anziché un valore costante. si ha segmentation fault solo quando si accede ad un array per la cui dichiarazione é stato sottratto un valore che ha fatto andare lo stack pointer oltre il limite dello stack.
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Mar 2005
Messaggi: 1653
|
Ah, ok! Grazie della spiegazione
__________________
gica78r@ncc-1701:~$ tar -c tar: Codardamente mi rifiuto di creare un archivio vuoto |
|
|
|
|
|
#16 | |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
|
|
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Oct 2006
Città: Roma
Messaggi: 1383
|
Quote:
penso che ci siano solo due modi di allocare dati dinamicamente: nello stack e nell'heap; il primo ha un limite (ad esempio impostato dal linker su Windows, non so su Linux), il secondo invece non ha virtualmente limite poiché é limitato solo dalla disponibilitá di indirizzi virtuali e di risorse di sistema; peró mentre per allocare nel primo é sufficiente una sottrazione, per allocare nel secondo é necessaria una chiamata di sistema con eventuale switch in kernel mode, quindi é inefficiente. se sta scritto da qualche parte che in C99 gli array la cui dimensione é espressa da una variabile devono essere allocati nell'heap allora é un motivo in piu per non usare il C99 |
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
No, intendevo una cosa diversa, tu l'hai trattato come se fosse un errore, ma in realtà non lo è.
Che finisca lo stack può succedere, ma al pari dell'allocazione classica se io utilizzo un intero troppo grande |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Ecco l'implementazione di questo codice:
Codice:
void f()
{
int n;
scanf("%d", &n);
int v[n];
while(n--);
}
Codice:
f: .LFB2: pushq %rbp .LCFI0: movq %rsp, %rbp .LCFI1: subq $48, %rsp .LCFI2: movq %fs:40, %rax movq %rax, -8(%rbp) xorl %eax, %eax movq %rsp, %rax movq %rax, -40(%rbp) leaq -12(%rbp), %rsi movl $.LC0, %edi movl $0, %eax call scanf movl -12(%rbp), %eax cltq salq $2, %rax addq $15, %rax addq $15, %rax shrq $4, %rax salq $4, %rax subq %rax, %rsp movq %rsp, -48(%rbp) movq -48(%rbp), %rax addq $15, %rax shrq $4, %rax salq $4, %rax movq %rax, -48(%rbp) movq -48(%rbp), %rax movq %rax, -24(%rbp) .L2: movl -12(%rbp), %eax testl %eax, %eax setne %dl subl $1, %eax movl %eax, -12(%rbp) testb %dl, %dl jne .L2 movq -40(%rbp), %rsp movq -8(%rbp), %rax xorq %fs:40, %rax je .L4 call __stack_chk_fail .L4: leave ret Non ho voglia di mettermi a leggerlo |
|
|
|
|
|
#20 | |
|
Senior Member
Iscritto dal: Jul 2002
Città: Provincia Tv
Messaggi: 1208
|
Quote:
Comunque evita come la peste questo costrutto: segmentation fault e' il migliore degli errori che possano accadere. Mi ricordo un esempio simile in c++ in cui se si usciva dalla lunghezza dell'array, si andava a modificare il valore di altre variabili automatiche presenti nello stack, senza controllo dei tipi. Poi voglio vedere a debuggare codice del genere. |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 15:12.






















