[Música tocando]
>> Doug LLOYD: OK, entón unha suxestión antes de iniciar aquí.
Se aínda non asistiu o vídeo en suxestións que pode querer facelo en primeiro lugar.
Porque este vídeo é outra forma de traballar con punteiros.
>> Por iso, vai falar sobre algúns conceptos
que cobren o Indicadores de vídeo, e estamos
vai pasar por riba deles agora, supoñendo que xa están
tipo de entendido.
Entón, iso é só o seu aviso xusto que, se está a ver este vídeo
e aínda non viu o video punteiros, pode tipo de
voar sobre a súa cabeza un pouco.
E por iso quizais sexa mellor para velo nesa orde.
>> Entón, nós xa vimos un forma de traballar con punteiros,
que é declaramos un variable, e entón nós
declarar outra variable, un punteiro variable, que apunta a el.
Entón creamos un variable cun nome, temos
creada unha segunda variable cun nome, e apuntamos que a segunda variable
en que en primeiro lugar.
Este tipo de ten un problema, porén, porque
obríganos a saber exactamente a cantidade de memoria que estamos
vai ter do momento noso programa está feita.
>> Por que é iso?
Porque temos que ser capaces de nomear ou identificar as posibles variables
poderiamos atopar.
Podemos ter unha matriz que se pode capaz de manter unha gran cantidade de información,
pero aínda non é exactamente suficientemente precisa.
E se nós non sabemos, E se non temos idea
o que imos ter en tempo de compilación?
Ou que o noso programa executado por un tempo moi longo,
aceptar varios usuario datos, e non podemos realmente
estimar si estamos Vai ter 1.000 unidades?
>> Non é como podemos dicir na liña de comandos
introducir cantos elementos pensas que vai ter.
Ben, o que se ese palpite é malo?
Distribución dinámica de memoria tipo de permítenos a camiño
para evitar este problema particular.
E a forma como el fai iso é usando punteiros.
>> Podemos usar punteiros para teña acceso aos dinamicamente
memoria alocada, memoria que está asignado como o programa está a ser executado.
Non é alocada en tempo de compilación.
Cando reservar dinamicamente memoria se trata dun pool
de memoria coñecido como o heap.
Anteriormente toda a memoria temos está a traballar con o curso
foi proveniente dunha piscina de memoria coñecida como a pila.
Unha boa forma de xeral manter en regra mente-- e este
non sempre son certas, pero practicamente case
mantén sempre é que calquera true-- vez que dá un nome de variable que
probablemente vive na pila.
E calquera hora que non facer dar unha variable dun nome,
que se pode facer con memoria dinámica distribución, el vive na pila.
>> Agora eu son o tipo de presentar isto como se hai estas dúas piscinas de memoria.
Pero pode ver este diagrama, que é xeralmente
unha representación de o que a memoria parece,
e nós non estamos indo a preocuparse todo o material da parte superior e na parte inferior.
O que nos interesa é esta parte en medio aquí, heap e pila.
Como verás por mirando para este diagrama,
estes non son, en realidade, dous grupos separados de memoria.
É un conxunto compartido de memoria onde comeza neste visuais
comeza na parte inferior e comezar a encher
dende o fondo coa pila, e comezar na parte superior e comezar a encher
arriba abaixo co heap.
Pero é realmente o mesmo pool, é só
spots diferentes, diferentes lugares na memoria que se están destinados.
E pode quedar sen memoria por un ou outro ter
o heap percorrer todo o camiño para a parte inferior, ou teñen
a pila de percorrer todo o camiño ata o cumio, ou que teñan a pila ea pila
atopar-se uns contra os outros.
Todos estes poden ser condicións que causan o seu programa
para realizar con falta de memoria.
Polo tanto, manter isto presente.
Cando falamos de a pila ea pila
estamos realmente fala de mesmo anaco xeral da memoria, só
diferentes porcións de que a memoria.
>> Entón, como é que imos chegar dinamicamente memoria alocada en primeiro lugar?
Como é que o noso programa comezar memoria como funciona?
Ben C ofrece unha función chamada malloc, alocador de memoria, o que
fai unha chamada, e pasar cantos bytes de memoria que quere.
Polo tanto, se o seu programa está a ser executado e quere un tempo de execución enteiro,
podes Mallock catro bytes de memoria, malloc parénteses catro.
>> Mallock vai pasar por mirando a través do conxunto,
porque estamos dinamicamente distribución de memoria,
e que vai voltar a vostede un punteiro para a memoria.
Non lle dá que memory-- non darlle un nome,
dálle un punteiro para el.
E é por iso que eu dixen de novo que é importante se cadra
asistiron o vídeo punteiros antes de chegar lonxe de máis para iso.
Entón malloc vai darlle de volta un punteiro.
>> Se Mallock non podo darlle calquera memoria porque executar para fóra,
el lle vai dar de volta un punteiro nulo.
Vostede recorda o que pasa se tentar eliminar a referencia un punteiro nulo?
Sufrimos un fallo seg, non?
Isto probablemente non é bo.
>> Así, cada vez que fai unha chamada para malloc sempre, sempre
que comprobar se é ou non o punteiro deulle de volta é nulo.
De ser, ten que rematar o seu programa porque se tentar e dereference
o punteiro nulo está indo sufrindo un fallo de segmento
eo seu programa é vai fallar de calquera maneira.
Así como nós estaticamente obter un enteiro?
>> int x.
Nós probablemente fixen iso unha morea de veces, non?
Isto xera unha variable chamada x que vive na pila.
Como podemos obter dinamicamente un enteiro?
Int estrela px igual malloc 4.
>> Ou, máis apropiadamente nós diriamos int estrela px
equivale ao tamaño de malloc de int, só para xogar un pouco menos
números máxicos sobre o noso programa.
Isto vai obter a nós catro bytes de memoria do heap,
eo punteiro chegamos de volta para el chámase px.
E entón, así como temos feito anteriormente nós
Pode eliminar a referencia para px acceder a esta memoria.
Como podemos obter un número enteiro do usuario?
Podemos dicir int x é igual a obter int.
Isto é moi sinxelo.
E se queremos crear unha matriz x de Carrozas que viven na pila?
flotar stack_array-- ese é o nome dos nosos corchetes array-- x.
Isto vai crear a nós un array x de Carrozas que viven na pila.
Podemos crear unha matriz de Carrozas que vive na pila tamén.
A sintaxe pode parecer un pouco máis complicado,
pero podemos dicir flotador estrela heap_array igual
malloc x veces o tamaño do flotador.
Necesito espacio suficiente para almacenar x valores de punto flotante.
Entón digo que teño 100 Carrozas, ou 1.000 coches alegóricos.
Así, nese caso, sería 400 bytes para 100 coches alegóricos,
ou 4.000 bytes para 1.000 coches alegóricos, porque cada flotador ocupa
catro bytes de espazo.
>> Despois de facelo podo usar o sintaxe paréntese en heap_array.
Así como eu faría stack_array, I Pode acceder seus elementos individualmente
usando heap_array cero, un heap_array.
Pero recordar a razón que podemos facelo porque é o nome dunha matriz en C
é realmente un punteiro para primeiro elemento deste conxunto.
Así, o feito de que estamos declarando un matriz de Carrozas na pila aquí
en realidade é un pouco erro.
Nós realmente estamos no segunda liña de código non
tamén a creación dun punteiro para unha peza de memoria que, a continuación, facer un traballo con.
>> Aquí está o gran problema con alocada dinamicamente a memoria, porén,
e é por iso que é realmente importante desenvolver uns bos hábitos
cando se está a traballar con el.
A diferenza declarada estaticamente memoria, a memoria
non é automaticamente devolta ao sistema cando a súa función é feito.
Entón, se temos de inicio, e principal chama unha función
f, cando f acabados sexa o que está facendo e devolve o control do programa
de volta á principal, toda a memoria que f usado é xa de volta.
Pode ser usado de novo por algún outro programa,
ou algunha outra función que chámase máis tarde na principal.
Pode utilizar a mesma memoria de novo.
>> Se dinamicamente reservar memoria aínda
ten que dicir explicitamente o sistema que está feito con el.
Vai coller-lo para ti, o que podería levar a un problema de vostedes esgotando
de memoria.
E, de feito, ás veces, refírense a para isto como unha perda de memoria.
E ás veces eses perdas de memoria realmente pode ser realmente devastador
para o desempeño do sistema.
>> Se vostede é un usuario frecuente internet pode usar certos navegadores web,
e eu non vou citar nomes aquí, pero existen algúns navegadores web aí fóra
que son notorias para realmente ter perdas de memoria que non son fixos.
E se deixa o seu navegador aberto para un período moi longo de tempo, días
e en días, ou semanas, ás veces Pode notar que o seu sistema
é correndo moi, moi lentamente.
E a razón para iso é que o explorador reservar memoria,
pero despois non contou o sistema que está feito con el.
E así que deixa menos memoria dispoñible para todos os seus programas
ter que compartir, porque é leaking-- que o navegador web
programa está vazando memoria.
Como é que imos dar de memoria de volta cando estamos a facer con el?
Ben, por sorte, é unha xeito moi doado de facelo.
Nós só libralo.
Hai unha función chamada libre, que acepta un enlace para a memoria,
e nós somos bos de ir.
>> Entón, imos dicir que estamos no medio do noso programa,
queremos malloc 50 caracteres.
Queremos malloc unha matriz que pode capaz de reter 50 caracteres.
E cando temos un punteiro de volta ao que, o nome do punteiro é a palabra.
Facemos o que somos vai facer palabra,
e, a continuación, cando estamos feito que só libralo.
E agora temos devolto os 50 bytes de memoria ao seu sistema.
Algunha outra función pode usalos.
Non temos que preocuparse un sufrimento escape de memoria porque temos liberado palabra.
Nós demos a memoria de volta, por iso, termine de traballar con el.
Polo tanto, hai tres regras de ouro que deben
ser mantido en conta sempre que está reservar dinamicamente a memoria
con malloc.
Cada bloque de memoria que malloc ten que ser liberado
antes do seu programa remata a execución.
Agora, de novo, no aparello ou no IDE este tipo de pasa para ti de todos os xeitos
você-- cando iso vai ocorrer de forma cando o programa é pechado,
toda a memoria será liberado.
Pero é xeralmente boa codificación práctica para sempre, cando estea listo,
liberar o que mallocd.
>> Dito isto, únicas cousas que tes mallocd deberían ser liberados.
Se declarar un estaticamente enteiro, int x e coma,
que vive na pila, vostede non, entón queremos liberar x.
Entón únicas cousas que mallocd deberían ser liberados.
>> E, para rematar, non facer algo libre dúas veces.
Isto pode levar a outra situación estraña.
Entón, todo o que tes mallocd debe ser liberado.
Únicas cousas que malloc deberían ser liberados.
E non facer algo libre dúas veces.
>> Entón, imos pasar por un exemplo aquí que algúns alocada dinamicamente
memoria pode parecer mixto con algunha memoria estática.
O que pode ocorrer aquí?
Vexa se pode seguir ao longo e difícil de adiviñar o que está
ocorrerá como nós imos a través de todas estas liñas de código.
>> Así, dicimos int m.
Que pasa aquí?
Ben, iso é moi sinxelo.
Eu crear unha variable enteira chamada m.
Eu colorase lo verde, porque esa é a cor
que eu uso cando estou falando preto de variables enteiras.
É unha caixa.
Chámase m, e pode almacenar números enteiros dentro del.
>> E se eu, a continuación, dicir int estrela un?
Ben, iso é moi semellante.
Estou creando unha caixa chamada a.
É capaz de explotación int estrelas, punteiros para enteiros.
Entón, eu estou colorido-verde-ish tamén.
>> Sei que ten algo que ver con un número enteiro,
pero ela propia non é un número enteiro.
Pero é practicamente a mesma idea.
Eu creei unha caixa.
Ambos dereita agora viven na pila.
Eu dei-lles ambos nomes.
>> int estrela b equivale ao tamaño de malloc de int.
Este pode ser un pouco complicado.
Leva un segundo e pensar sobre o que era de esperar que suceda neste diagrama.
int estrela b equivale ao tamaño de malloc de int.
>> Ben, iso non basta crear unha caixa.
Isto realmente crea dúas caixas.
E se liga, tamén establece un punto nunha relación.
Temos asignado a unha pista de memoria na pila.
Teña en conta que a caixa superior dereita alí non ten un nome.
>> Nós mallocd-lo.
Existe na pila.
Pero b ten un nome.
É unha variable punteiro chamado b.
Que vive na pila.
>> Polo tanto, é unha peza de memoria que apunta a outro.
b contén a dirección do bloque de memoria.
Non ten un nome de outra forma.
Pero apunta a iso.
Así, cando dicimos int estrela b é igual a malloc tamaño do int, que alí mesmo,
que a frecha que apareceu na lado dereito alí, aquela cousa toda,
Vou ter que aparecer de novo, é o que pasa.
Todo isto acontece que unha soa liña de código.
Agora imos chegar algo máis simple de novo.
un é igual e comercial m.
Vostede recorda o que un é igual e comercial m é?
Ben, iso é un recibe o enderezo de m.
Ou poñer máis esquemáticamente, algúns puntos para m.
>> b é igual a un.
Aceptar entón aquí está outro.
Un igual ao b.
O que vai ocorrer o diagrama esta vez?
>> Ben recordar que o obras operador de asignación
atribuíndo o valor no dereito do valor do lado esquerdo.
Entón, en vez de un enlace para m, unha empresa apunta para o mesmo lugar que b puntos.
un non apunta a B, A puntos onde b puntos.
>> Un agroma para b que faría ser un igual e comercial b.
Pero, en vez de un é igual ab só significa que a e b son agora
apuntando para o mesmo enderezo, porque dentro b é só un enderezo.
E agora dentro dun é o mesmo enderezo.
m é igual a 10, probablemente o O máis sinxelo
fixemos un pouco.
Pon a 10 no cadro.
Estrela b é igual a m plus 2, marca de nosa punteiros vídeo que estrela b significa.
Estamos indo para dereference b e put algún valor en que a localización de memoria.
Neste caso 12.
>> Entón, cando dereference un punto de recordar que acabamos de viaxar baixo a frecha.
Ou dito doutra forma, ir a este enderezo de memoria
e manipula-lo de algunha maneira.
Poñemos un valor alí.
Neste caso estrela b é igual a m máis 2 é só
ir á variable apuntada por b, ir á memoria apuntada por b,
e poñer máis 2 m de alí, 12.
>> Agora eu liberar b.
Que pasa cando liberar b?
Lembre que eu dixen medios libres.
O que estou dicindo cando liberar b?
>> Estou canso de traballar con el, non?
Eu esencialmente desistir da memoria.
Doulle ao seu sistema.
Eu non teño máis diso é o que eu estou dicindo a eles, OK?
>> Agora, se eu digo unha estrela é igual a 11 probablemente pode
xa dicir que algo malo que vai pasar aquí, non?
E, de feito, se eu tente que eu probablemente sufriría un fallo de segmento.
Porque agora, aínda anteriormente que pedazo de memoria
era algo que tiña acceso, neste punto
Agora eu estou accedendo memoria que non é legal para min para acceder.
>> E como nós, probablemente, lembro, cando acceder a memoria
que non se quere tarifas, esa é a causa máis común
dunha segmentación fallo. E así o meu programa
deixaría de funcionar se eu intentase facer.
Entón, de novo, é unha boa idea para obter un bo prácticas e bos hábitos enraizados
cando se traballa con malloc e libre, de xeito que non sofre de segmentación
fallos, e que utiliza seu alocada dinamicamente
memoria de forma responsable.
>> Eu son Doug Lloyd este é CS50.