View Full Version : [c++] heap, stack, array
Barbalbero
16-12-2007, 09:24
Ciao a tutti...
In principio era il Borland.
La sua regola era:
non dichiarare mai un array del tipo
int numero;
...
int array[numero];
Voleva un'espressione costante, tra le parentesi quadre.
Ora noto che i tempi son cambiati, poiché dev c++ permette di far ciò. Questo significa che è cambiato qualcosa a livello sostanziale, tra i 2 compilatori? Significa che Borland allocava gli array nello stack e dev c++ li alloca nello heap?
Non dovrebbe essere standardizzata questa cosa?
Significa che potresti incorrere in gravi problemi perché non hai inizializzato numero :asd:
Le variabili locali vengono allocate sempre nello stack, però suppongo che in quel caso ci siano dei barbatrucchi del compilatore...o che alloca solo questo array nello heap (nel caso numero venga inizializzato dopo) o che con un gioco di sostituzioni vada a prendere il valore di inizializzazione di numero (nel caso numero venga inizializzato subito).
IMHO sarebbe comunque meglio non usare questa possibilità, perché appunto messa a disposizione dal compilatore.
Barbalbero
16-12-2007, 10:40
Significa che potresti incorrere in gravi problemi perché non hai inizializzato numero :asd:
Beh... tra i puntini era ovviamente sottinteso che ci stava anche l'inizializzazione del numero...
Io credo che lo allochi nello heap, perché lo stack, se non ricordo male, viene caricato subito all'esecuzione del programma...
Io credo che lo allochi nello heap, perché lo stack, se non ricordo male, viene caricato subito all'esecuzione del programma...
Sì, credo anche io. Però ad esempio, in un caso come questo:
int numero = 9;
int v[numero];
il compilatore riesce a capire facilmente il valore da assegnare a numero con una semplice sostituzione in fase di compilazione e questo gli permetterebbe comunque di determinare la quantità di memoria da riservare nello stack.
E' questo il caso che mi fa più pensare allo heap:
int numero;
cin >> numero;
int v[numero];
Comunque te lo dico subito cosa fa ;)
Barbalbero
16-12-2007, 11:05
sì in quel caso sì, ma nel mio caso apro un file, carico un intero che è la dimensione dell'array e poi dichiaro l'array della dimensione di tale intero. Questo non è fattibile col solo ausilio dello stack.
sì comunque ci sarà qualche barbatrucco del compilatore... magari qualche malloc che lui fa senza dirlo a nessuno...boh... insomma non è un problema esistenziale... solo che mi chiedo se sia formalmente corretto utilizzare questi nuovi array dinamici, ad esempio in un esame universitario o alle olimpiadi dell'informatica
Sorgente C++:
#include <iostream>
void miaf()
{
int numero;
std::cin >> numero;
int v[numero];
}
main()
{
miaf();
}
Sorgente asm:
.file "prova.cpp"
.section .ctors,"aw",@progbits
.align 8
.quad _GLOBAL__I__Z4miafv
.text
.align 2
.type _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB1409:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
subq $16, %rsp
.LCFI2:
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
cmpl $1, -4(%rbp)
jne .L5
cmpl $65535, -8(%rbp)
jne .L5
movl $_ZSt8__ioinit, %edi
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, %edx
movl $0, %esi
movl $__tcf_0, %edi
call __cxa_atexit
.L5:
leave
ret
.LFE1409:
.size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
.globl __gxx_personality_v0
.align 2
.type _GLOBAL__I__Z4miafv, @function
_GLOBAL__I__Z4miafv:
.LFB1411:
pushq %rbp
.LCFI3:
movq %rsp, %rbp
.LCFI4:
movl $65535, %esi
movl $1, %edi
call _Z41__static_initialization_and_destruction_0ii
leave
ret
.LFE1411:
.size _GLOBAL__I__Z4miafv, .-_GLOBAL__I__Z4miafv
.align 2
.type __tcf_0, @function
__tcf_0:
.LFB1410:
pushq %rbp
.LCFI5:
movq %rsp, %rbp
.LCFI6:
subq $16, %rsp
.LCFI7:
movq %rdi, -8(%rbp)
movl $_ZSt8__ioinit, %edi
call _ZNSt8ios_base4InitD1Ev
leave
ret
.LFE1410:
.size __tcf_0, .-__tcf_0
.globl _Unwind_Resume
.align 2
.globl _Z4miafv
.type _Z4miafv, @function
_Z4miafv:
.LFB1401:
pushq %rbp
.LCFI8:
movq %rsp, %rbp
.LCFI9:
subq $64, %rsp
.LCFI10:
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movq %rsp, %rax
movq %rax, -40(%rbp)
leaq -12(%rbp), %rsi
movl $_ZSt3cin, %edi
.LEHB0:
call _ZNSirsERi
.LEHE0:
movl -12(%rbp), %eax
cltq
subq $1, %rax
salq $2, %rax
addq $4, %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)
movq -40(%rbp), %rsp
jmp .L12
.L14:
movq %rax, -56(%rbp)
.L11:
movq -56(%rbp), %rax
movq -40(%rbp), %rsp
movq %rax, -56(%rbp)
movq -56(%rbp), %rdi
.LEHB1:
call _Unwind_Resume
.LEHE1:
.L12:
movq -8(%rbp), %rax
xorq %fs:40, %rax
je .L13
call __stack_chk_fail
.L13:
leave
ret
.LFE1401:
.size _Z4miafv, .-_Z4miafv
.section .gcc_except_table,"a",@progbits
.LLSDA1401:
.byte 0xff
.byte 0xff
.byte 0x1
.uleb128 .LLSDACSE1401-.LLSDACSB1401
.LLSDACSB1401:
.uleb128 .LEHB0-.LFB1401
.uleb128 .LEHE0-.LEHB0
.uleb128 .L14-.LFB1401
.uleb128 0x0
.uleb128 .LEHB1-.LFB1401
.uleb128 .LEHE1-.LEHB1
.uleb128 0x0
.uleb128 0x0
.LLSDACSE1401:
.text
.align 2
.globl main
.type main, @function
main:
.LFB1402:
pushq %rbp
.LCFI11:
movq %rsp, %rbp
.LCFI12:
call _Z4miafv
movl $0, %eax
leave
ret
.LFE1402:
.size main, .-main
.local _ZSt8__ioinit
.comm _ZSt8__ioinit,1,1
.weakref _Z20__gthrw_pthread_oncePiPFvvE,pthread_once
.weakref _Z27__gthrw_pthread_getspecificj,pthread_getspecific
.weakref _Z27__gthrw_pthread_setspecificjPKv,pthread_setspecific
.weakref _Z22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create
.weakref _Z22__gthrw_pthread_cancelm,pthread_cancel
.weakref _Z26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock
.weakref _Z29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock
.weakref _Z28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock
.weakref _Z26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init
.weakref _Z26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create
.weakref _Z26__gthrw_pthread_key_deletej,pthread_key_delete
.weakref _Z30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init
.weakref _Z33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype
.weakref _Z33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0x0
.byte 0x1
.string "zPLR"
.uleb128 0x1
.sleb128 -8
.byte 0x10
.uleb128 0x7
.byte 0x3
.long __gxx_personality_v0
.byte 0x3
.byte 0x3
.byte 0xc
.uleb128 0x7
.uleb128 0x8
.byte 0x90
.uleb128 0x1
.align 8
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB1409
.long .LFE1409-.LFB1409
.uleb128 0x4
.long 0x0
.byte 0x4
.long .LCFI0-.LFB1409
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE1:
.LSFDE3:
.long .LEFDE3-.LASFDE3
.LASFDE3:
.long .LASFDE3-.Lframe1
.long .LFB1411
.long .LFE1411-.LFB1411
.uleb128 0x4
.long 0x0
.byte 0x4
.long .LCFI3-.LFB1411
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI4-.LCFI3
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE3:
.LSFDE5:
.long .LEFDE5-.LASFDE5
.LASFDE5:
.long .LASFDE5-.Lframe1
.long .LFB1410
.long .LFE1410-.LFB1410
.uleb128 0x4
.long 0x0
.byte 0x4
.long .LCFI5-.LFB1410
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI6-.LCFI5
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE5:
.LSFDE7:
.long .LEFDE7-.LASFDE7
.LASFDE7:
.long .LASFDE7-.Lframe1
.long .LFB1401
.long .LFE1401-.LFB1401
.uleb128 0x4
.long .LLSDA1401
.byte 0x4
.long .LCFI8-.LFB1401
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI9-.LCFI8
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE7:
.LSFDE9:
.long .LEFDE9-.LASFDE9
.LASFDE9:
.long .LASFDE9-.Lframe1
.long .LFB1402
.long .LFE1402-.LFB1402
.uleb128 0x4
.long 0x0
.byte 0x4
.long .LCFI11-.LFB1402
.byte 0xe
.uleb128 0x10
.byte 0x86
.uleb128 0x2
.byte 0x4
.long .LCFI12-.LCFI11
.byte 0xd
.uleb128 0x6
.align 8
.LEFDE9:
.ident "GCC: (GNU) 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)"
.section .note.GNU-stack,"",@progbits
Sono invecchiato e non ci capisco più una cippa :confused: :asd:
Poi ci si mettono anche le istruzioni a 64 bit :O
Comunque ad occhio ingrandisce dinamicamente lo spazio riservato nello stack.
Barbalbero
16-12-2007, 11:42
:confused:
sì boh
:D
tomminno
17-12-2007, 12:00
IMHO sarebbe comunque meglio non usare questa possibilità, perché appunto messa a disposizione dal compilatore.
Questa è una bellissima feature del C99.
Stack overflow a gogo.
Non è lo stesso comportamento della funzione alloca di C ? Anche lei alloca dinamicamente nello stack. Magari viene richiamata proprio questa funzione.
Barbalbero
17-12-2007, 13:00
Non è lo stesso comportamento della funzione alloca di C ? Anche lei alloca dinamicamente nello stack. Magari viene richiamata proprio questa funzione.
Ma scusate.... se lo stack è la memoria che viene allocata appena viene caricato il programma, questa non è fissa (o limitata)?
Non credo di aver capito bene...
Ma scusate.... se lo stack è la memoria che viene allocata appena viene caricato il programma, questa non è fissa (o limitata)?
Non credo di aver capito bene...
Si, è limitato, ma non lo pieni del tutto subito. Se non erro, sotto Linux è 8 mb . Però puoi allocare dinamicamente anche lì dentro, ovviamente con grossi rischi di stack overflow.
Certo, la dimensione dello stack è fissata al momento del caricamento dell'immagine eseguibile in memoria.
Non è che di fatto viene ridimensionato lo stack, ma lo spazio riservato nello stack per le variabili automatiche locali alla funzione.
Barbalbero
17-12-2007, 13:09
ah ok ora è chiaro... grazie :D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.