[RISOLTO] [C] Matrice allocata dinamicamente

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.
Rispondi
Avatar utente
boh
Linux 4.x
Linux 4.x
Messaggi: 1027
Iscritto il: ven 16 set 2005, 0:00
Slackware: 14.2 (x64)
Kernel: 4.4.111
Desktop: KDE 4.14.32
Località: Milano
Contatta:

[RISOLTO] [C] Matrice allocata dinamicamente

Messaggio da boh »

Ciao a tutti!
Sto lavorando ad un progetto e ho bisogno di usare una matrice le cui dimensioni sono lunghezze di stringhe passate come parametri al main e quindi note solo a runtime.
Nel main alloco le stringhe, ne recupero la lunghezza e poi passo tutto a una funzione (le due stringhe (char*) più le lunghezze (int)).
Nella funzione ho dichiarato una matrice usando le lunghezze delle stringhe come dimensioni.
Tutto funzionava a dovere, fino a quando sono arrivato a dover usare stringhe di lunghezza > 2000 (per intenderci, sarebbero sequenze di DNA, quindi è logico che siano così lunghe). Con stringhe così lunghe ho ottenuto una bellissima segmentation fault.
Ne consegue che ho la necessità di allocare la matrice dinamicamente. Ho letto in giro un po' di modi, tra cui il più comune è il seguente:

Codice: Seleziona tutto

int **score, i;

// Allocazione righe
if ((score = malloc(len1*sizeof(int*))) == NULL)
	return -1;

// Allocazione colonne
for(i=0; i<len1; i++) {
        if ((score[i] = malloc(sizeof(int) * len2) == NULL)
                return -1;
}
Avrei un paio di domande a riguardo:
  • È l'unico modo in cui posso allocare la matrice o è possibile farlo con un'unica malloc (con una conseguente unica free)?
  • Più avanti accedo agli elementi della matrice nel modo usuale (score[j]); vorrei non dover cambiare tutto. Avrò problemi in tal senso con l'allocazione dinamica?


EDIT: la free sarebbe corretta in questo modo?

Codice: Seleziona tutto

for(i=0; i < len1; i++)
		free(score[i]);

free(score);
Ultima modifica di boh il mer 15 gen 2014, 23:36, modificato 2 volte in totale.
"Be yourself. Everyone else is already taken." ~ Oscar Wilde

Avatar utente
Vito
Staff
Staff
Messaggi: 4180
Iscritto il: mar 5 dic 2006, 17:28
Nome Cognome: Vito
Desktop: MacOS
Località: Monaco (DE)
Contatta:

Re: [C] Matrice allocata dinamicamente

Messaggio da Vito »

boh ha scritto: È l'unico modo in cui posso allocare la matrice o è possibile farlo con un'unica malloc (con una conseguente unica free)?
Mi sa che è l'unico modo (è noioso lo so..).

boh ha scritto:Più avanti accedo agli elementi della matrice nel modo usuale (score[j]); vorrei non dover cambiare tutto. Avrò problemi in tal senso con l'allocazione dinamica?

Assolutamente no (ovviamente rispettando le dimensioni della matrice).
Quando dichiari un array, altro non fai che dichiarare un puntatore.
Poi se ne dichiari uno allocato staticamente, questo viene allocato sullo stack e della sua allocazione/deallocazione se ne occupa il compilatore.
Se ne dichiari uno dinamico, spetta a te allocare/deallocare, e l'array viene allocato in area heap.
La gestione è esattamente la stessa.
"Stat rosa pristina nomina, nomina nuda tenemus." [ Umberto Eco - Il nome della rosa]

"Faber est suae quisque fortunae ." [ Appio Claudio Cieco]

Avatar utente
Blallo
Packager
Packager
Messaggi: 3298
Iscritto il: ven 12 ott 2007, 11:37
Nome Cognome: Savino Liguori
Slackware: 14.2 / 12.2
Kernel: 4.4.14-smp
Desktop: DWM
Località: Torino / Torremaggiore (FG)
Contatta:

Re: [C] Matrice allocata dinamicamente

Messaggio da Blallo »

boh ha scritto:È l'unico modo in cui posso allocare la matrice o è possibile farlo con un'unica malloc (con una conseguente unica free)?
Si, è l'unico modo.
Ma fidati, è anche più pratico. :)
boh ha scritto:Più avanti accedo agli elementi della matrice nel modo usuale (score[j]); vorrei non dover cambiare tutto. Avrò problemi in tal senso con l'allocazione dinamica?

No, una volta allocata, alla matrice si accede sempre in un modo.
Ricordati che sono pur sempre puntatori (e pertanto puntatore++ punta all'elemento successivo).
boh ha scritto:EDIT: la free sarebbe corretta in questo modo?

Codice: Seleziona tutto

for(i=0; i < len1; i++)
		free(score[i]);

free(score);
Si.

Avatar utente
boh
Linux 4.x
Linux 4.x
Messaggi: 1027
Iscritto il: ven 16 set 2005, 0:00
Slackware: 14.2 (x64)
Kernel: 4.4.111
Desktop: KDE 4.14.32
Località: Milano
Contatta:

Re: [C] Matrice allocata dinamicamente

Messaggio da boh »

Grazie ad entrambi per le risposte :D
Un'ultima domanda non strettamente correlata: ho notato che se passo in input stringhe troppo lunghe bash non le prende (interpreta la parte "di troppo" come un nuovo comando).
Come posso ovviare a questo problema?
"Be yourself. Everyone else is already taken." ~ Oscar Wilde

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6556
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: [C] Matrice allocata dinamicamente

Messaggio da targzeta »

Cosa intendi con "troppo lunghe"? Quanti caratteri?

Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà 

Avatar utente
boh
Linux 4.x
Linux 4.x
Messaggi: 1027
Iscritto il: ven 16 set 2005, 0:00
Slackware: 14.2 (x64)
Kernel: 4.4.111
Desktop: KDE 4.14.32
Località: Milano
Contatta:

Re: [C] Matrice allocata dinamicamente

Messaggio da boh »

Vorrei arrivare a dare in input due stringhe da 16000 caratteri l'una.
"Be yourself. Everyone else is already taken." ~ Oscar Wilde

Avatar utente
targzeta
Iper Master
Iper Master
Messaggi: 6556
Iscritto il: gio 3 nov 2005, 14:05
Nome Cognome: Emanuele Tomasi
Slackware: 64-current
Kernel: latest stable
Desktop: IceWM
Località: Carpignano Sal. (LE) <-> Pisa

Re: [C] Matrice allocata dinamicamente

Messaggio da targzeta »

Dovrebbe essere possibile. Non è che tra questi caratteri c'è qualche '&' o caratteri da quotare?

Emanuele
Linux Registered User #454438
Se pensi di essere troppo piccolo per fare la differenza, prova a dormire con una zanzara -- Dalai Lama
20/04/2013 - Io volevo Rodotà 

Avatar utente
brg
Linux 2.x
Linux 2.x
Messaggi: 490
Iscritto il: sab 12 mar 2011, 14:20
Slackware: 14.2
Kernel: 4.4.172
Desktop: KDE4
Località: Montecatini
Contatta:

Re: [C] Matrice allocata dinamicamente

Messaggio da brg »

Come glieli passi gli argomenti? Dubito che tu scriva 16000 caratteri a mano. Ad ogni modo se esegui getconf -a | grep ARG_MAX ottieni la lunghezza massima della stringa di parametri passabili ad un programma, circa 2.000.000 sul kernel standard di Slackware64.

Non sarebbe più comodo far leggere i dati da un file?

Avatar utente
boh
Linux 4.x
Linux 4.x
Messaggi: 1027
Iscritto il: ven 16 set 2005, 0:00
Slackware: 14.2 (x64)
Kernel: 4.4.111
Desktop: KDE 4.14.32
Località: Milano
Contatta:

Re: [C] Matrice allocata dinamicamente

Messaggio da boh »

ARG_MAX effettivamente è poco più di 2M, quindi non dovrebbero esserci problemi. Le stringhe sono due e le passo come argv[1] e argv[2], quindi come parametri del main.
Le faccio generare da un generatore online su un alfabeto di soli 4 caratteri (ACGT come le sequenze genetiche) e poi copio-incollo in bash.

Ho riprovato e ha funzionato, quindi siamo a posto :D
Non so perchè mi aveva dato quel problema!

Metto risolto e grazie a tutti per le risposte! =D>
"Be yourself. Everyone else is already taken." ~ Oscar Wilde

Rispondi