DOMANDA stringhe e puntatori in C

theprogrammer.99

Nuovo Utente
96
34
Quindi in memoria i dati(tutto ciò che viene caricato in memoria?) si memorizzano in spazi contigui. Non lo sapevo. Grazie.

Questo non dipende dal linguaggio ma dalle primitive di allocazione di memoria che il sistema mette a disposizione. Ad esempio la malloc/calloc utilizzano API di basso livello del sistema operativo che restituiscono blocchi di memoria contigui.

memoria estesa (è quella che i programmatori chiamano Heap?)?

No, non si chiama memoria "estesa" e sì, a grandi linee la memoria viene allocata nell'heap di sistema.
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Non sono in grado di seguirti per ora. Quindi le funzioni malloc e calloc hanno a che fare con la gestione della memoria estesa(è quella che i programmatori chiamano Heap?)?

In realtà non ho detto nulla di particolare, se non mostrarti che con o senza quadre l'indirizzo è sempre il medesimo; inoltre ho aggiunto che in C non avviene un controllo sugli indici degli array: quindi se hai un array di 10 elementi e accedi alla posizione 11, te lo fa fare.

Come dice theprogrammer, non si chiama "estesa".
malloc/calloc restituiscono un puntatore a della memoria allocata nell'heap, si (poi su cosa facciano davvero, è inutile parlarne ora, per non confonderti ulteriormente le idee).
 
  • Mi piace
Reazioni: BAT

Andretti60

Utente Èlite
6,440
5,091
Quello che cerchi di fare non è banale.
Certo, puoi reindirizzare l’input e usare scanf() per mettere il file in u a stringa (se il file è di testo) ma la stringa la devi allocare prima di usarla, e come fai ad allocarla se non sai la dimensione del file? E anche se sai la dimensione, devi accertarti che hai abbastanza memoria per allocarla, se il file è troppo grosso è possibile che non ce la fai, o se puoi poi il programma impiegherà un vita per allocare la memoria e leggere il file (in quanto scanf() legge in maniera formattata).

Ma a parte questo, l risposta alla tua domanda è si, in un programma vettori e stringhe (la stringa non è poi altro che un vettore) sono memorizzare in maniera contigua per cui accedere ai singoli elementi è estremamente veloce.
 

BAT

Moderatore
Staff Forum
Utente Èlite
22,944
11,580
CPU
1-Neurone
Dissipatore
Ventaglio
RAM
Scarsa
Net
Segnali di fumo
OS
Windows 10000 BUG
davvero strano! prova col copia-incolla del carattere corrispondente, te li lascio qui:
[
]
 

_Achille

Utente Èlite
3,067
725
CPU
Intel i5-6600K @4.6 GHz
Dissipatore
Cryorig H5
Scheda Madre
ASRock Z170 Extreme 6
HDD
WesternDigital 1TB & Crucial MX200 250GB
RAM
Corsair Ven 16GB DDR4 2133MHz
GPU
Sapphire RX 580 Nitro+
Monitor
Dell S2418H
PSU
RM550X
Case
NZXT S340
Periferiche
Anne Pro 2, Razer Abyssus
OS
Windows 10 Pro
Credo intenda che venga riconosciuto come BBCode.

Il codice va racchiuso tra il tag CODE o ICODE
 
  • Mi piace
Reazioni: Mursey

cuttyflam

Nuovo Utente
21
2
Quello che cerchi di fare non è banale.
Certo, puoi reindirizzare l’input e usare scanf() per mettere il file in u a stringa (se il file è di testo) ma la stringa la devi allocare prima di usarla, e come fai ad allocarla se non sai la dimensione del file? E anche se sai la dimensione, devi accertarti che hai abbastanza memoria per allocarla, se il file è troppo grosso è possibile che non ce la fai, o se puoi poi il programma impiegherà un vita per allocare la memoria e leggere il file (in quanto scanf() legge in maniera formattata).

Scusi la mia ignoranza. Quello che voglio dire è che comunque i byte presenti in memoria non vanno formattati per leggerli sotto forma di numeri, lettere, ecc...?

Ma a parte questo, l risposta alla tua domanda è si, in un programma vettori e stringhe (la stringa non è poi altro che un vettore) sono memorizzare in maniera contigua per cui accedere ai singoli elementi è estremamente veloce.

Per me è importante saperlo! Grazie.
Post unito automaticamente:

davvero strano! prova col copia-incolla del carattere corrispondente, te li lascio qui:
[
]
[
]

Col copia e incolla vengono fuori
mentre con

str

scompaiono per l'appunto!(Già visto con l'anteprima)
 
Ultima modifica:

_Achille

Utente Èlite
3,067
725
CPU
Intel i5-6600K @4.6 GHz
Dissipatore
Cryorig H5
Scheda Madre
ASRock Z170 Extreme 6
HDD
WesternDigital 1TB & Crucial MX200 250GB
RAM
Corsair Ven 16GB DDR4 2133MHz
GPU
Sapphire RX 580 Nitro+
Monitor
Dell S2418H
PSU
RM550X
Case
NZXT S340
Periferiche
Anne Pro 2, Razer Abyssus
OS
Windows 10 Pro
Per me è importante saperlo! Grazie.
È la caratteristica che definisce il concetto di array, insieme all’accesso degli elementi con complessità costante O(1).


Scusi la mia ignoranza. Quello che voglio dire è che comunque i byte presenti in memoria non vanno formattati per leggerli sotto forma di numeri, lettere, ecc...?
Sì chiaramente, ma credo che intenda che se vuoi leggere un file lettera per lettera e allocare lo spazio esatto ogni volta, ciò diventa complessivamente pesante per le ripetute chiamate a fscanf (e realloc pure). O almeno è quello che io interpreto.

Ma non ho capito come si è arrivati a questo. Il thread inizialmente parlava della conversione da array a puntatore.
 

cuttyflam

Nuovo Utente
21
2
È la caratteristica che definisce il concetto di array, insieme all’accesso degli elementi con complessità costante O(1).



Sì chiaramente, ma credo che intenda che se vuoi leggere un file lettera per lettera e allocare lo spazio esatto ogni volta, ciò diventa complessivamente pesante per le ripetute chiamate a fscanf (e realloc pure). O almeno è quello che io interpreto.

Ma non ho capito come si è arrivati a questo. Il thread inizialmente parlava della conversione da array a puntatore.

Comunque ci siamo arrivati per quanto riguarda la mia domanda.
 

theprogrammer.99

Nuovo Utente
96
34
Ma dove stati studiando il C? Hai un libro? Lo stai seguendo?

Avere le idee confuse va bene, ma si chiariscono solo studiando, non facendo domande senza molto senso.
 

pabloski

Utente Èlite
2,868
916
Wow, vedo una massiccia confusione nei post di cuttyflam. Intanto perchè continui ad usare termini tipicamente del DOS, tipo "terminale del DOS" e "memoria estesa"?

Sono concetti che non dovrebbero far parte del libro che stai usando per studiare il C ( almeno spero ). E ti stanno portando fuori strada. Per esempio, quando dici che heap = memoria estesa, stai sbagliando di grosso.

Heap e stack sono due modi di gestire la memoria. E si, il sistema operativo si preoccupa d'individuare due aree di memoria distinte in cui "allocare" queste due tipologie di memoria ( termine improprio, ma lasciamolo passare ).

Il punto è che lo stack ( nella stragrande maggioranza dei linguaggi ) è gestito automaticamente dal runtime del linguaggio e non esplicitamente dal programmatore. Mentre l'heap si, nei linguaggi di sistema tipo C, C++, Rust, Pascal, D, ecc... In linguaggi come Python, nemmeno quello puoi gestire.

E qui si arriva a malloc/free/new/delete, che sono le funzioni e parole chiave per allocare/deallocare zone dell'heap, ottenendo puntatori all'inizio di tali zone.

La contiguità di cui parlavi, è presente in alcuni casi ma non sempre. Un array sta su un blocco contiguo di memoria ( che sia heap o stack, dipende da come l'hai dichiarato nel programma ). Una lista linkata non sta su un unico blocco contiguo di memoria, ma ha i suoi elementi sparpagliati in tutto l'heap.

Per tornare alla tua domanda iniziale, una variabile di tipo stringa ( char [] ) è un array di caratteri e tutte le variabili che fanno riferimento agli array, contengono in realtà l'indirizzo ( il puntatore ) della locazione di memoria dove inizia l'array. NON SONO PUNTATORI!!! Per accedere a s ( nel codice sotto ) scrivi s, non scrivi *s come faresti con un puntatore. Ma puoi applicare l'aritmetica dei puntatori a questi "riferimenti".

Quindi si, una variabile referente una stringa è un "puntatore" all'area di memoria contigua ( array di caratteri ) contenente la stringa.

E ovviamente puoi avere

C:
char s[] = "Ciao mondo";    // stringa allocata nello stack
char *t = malloc(1024);        // stringa allocata nell'heap

strncpy(t, s, strlen(s));

printf("s = %s\n", s+1);         // s+1 funziona, come se s fosse un puntatore!!
 
  • Mi piace
Reazioni: BAT
U

Utente cancellato 371741

Ospite
Memoria "estesa" e' una definizione PC dei tempi del gate A20. Non ha nulla a che vedere con il C. Non ti interessa quale memoria sia, malloc e calloc ovviamente le puoi usare in un micro 8 bit come in amd 64bit 24 thread. Meoria e' presa dall'heap, un "area" di memoria utilizzabile per allocazioni dinamiche.
Post unito automaticamente:

E ovviamente puoi avere

C:
char s[] = "Ciao mondo";    // stringa allocata nello stack
char *t = malloc(1024);        // stringa allocata nell'heap

strncpy(t, s, strlen(s));

printf("s = %s\n", s+1);         // s+1 funziona, come se s fosse un puntatore!!

Non per fare la "pigna" che precisa sciocchezze, eh, ma buona norma sempre controllare il ritorno di malloc:

Codice:
char *t = malloc(1024);        // stringa allocata nell'heap

if (t) {
        strncpy(t, s, strlen(s));
  ... bla bla ...
}
E' solo buona pratica.
 
Ultima modifica da un moderatore:

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili