[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.