[REPRODUCCIÓN DE MÚSICA] DOUG LLOYD: OK por lo que una sugerencia antes de comenzar aquí. Si no has visto el video en Punteros es posible que desee hacerlo primero. Debido a que este es otro de vídeo forma de trabajar con punteros. Así que va a hablar sobre algunos conceptos que cubrimos en el punteros de vídeo, y estamos va a pasar por encima de ellos ahora, asumiendo que ya están tipo de entendido. Así que eso es sólo su advertencia justa que si usted está viendo este vídeo y no se ha visto el vídeo punteros, podría especie de volar sobre su cabeza un poco. Y por lo que podría ser mejor al verlo en ese orden. Así que ya hemos visto uno manera de trabajar con los punteros, que es declaramos un variables, y luego declarar otra variable, un puntero variable que apunta a la misma. Para ello hemos creado una variable con un nombre, tenemos creado una segunda variable con un nombre, y señalamos que la segunda variable en ese primero. Este tipo de cuenta con un problema, sin embargo, debido a que nos obliga a saber exactamente la cantidad de memoria que estamos va a necesitar el momento nuestro programa es compilado. ¿Porque es eso? Porque tenemos que ser capaces de nombrar o identificar todas las posibles variables podríamos encontrar. Puede ser que tengamos una serie que podría ser capaz de mantener una gran cantidad de información, pero todavía no es exactamente lo suficientemente preciso. ¿Qué pasa si no sabemos, ¿y si no tenemos ni idea cuánto vamos a necesitar en tiempo de compilación? ¿O qué si nuestro programa lo hará correr por un tiempo muy largo, aceptando varios usuarios de datos, y no podemos realmente Estimamos si somos va a necesitar 1.000 unidades? No es que podamos decir en la línea de comandos introducir el número de artículos usted piensa que usted necesita. Bueno, ¿y si esa suposición no es correcta? Asignación de memoria dinámica tipo de nos permite el camino para evitar este problema en particular. Y la forma en que lo hace es mediante el uso de punteros. Podemos utilizar punteros a obtener acceso a dinámicamente memoria asignada, la memoria que es asignado como su programa se está ejecutando. No es asignado en tiempo de compilación. Al asignar dinámicamente memoria se trata de una pila de la memoria conocido como el montón. Anteriormente toda la memoria que hemos estado trabajando con en el curso ha estado viniendo de una piscina de la memoria conocida como la pila. Una buena manera de general tener en mente-- y esta regla no siempre ser verdad, pero casi casi Siempre vale cierto-- es que cualquier vez que das un nombre de variable que probablemente vive en la pila. Y en cualquier momento que no lo hacen dar a una variable un nombre, que se puede ver con la memoria dinámica la asignación, que vive en el montón. Ahora estoy un poco de presentar esto como si hay estas dos piscinas de memoria. Pero es posible que haya visto este diagrama, que es generalmente una representación de lo que la memoria se parece, y no vamos a preocuparse por todo las cosas en la parte superior y la parte inferior. Lo que nos importa es esta parte de el medio aquí, pila y pila. Como se puede ver por mirando este diagrama, estos en realidad no son dos piscinas separadas de la memoria. Es una piscina compartida de la memoria donde se inicia, en este visual se inicia en la parte inferior y empezar a llenar desde el fondo con la pila, y se comenzar en la parte superior y empezar a llenar de arriba hacia abajo con el montón. Pero lo que realmente es la mismo grupo, es sólo diferentes puntos, diferentes ubicaciones en la memoria que se están asignado. Y usted puede quedarse sin memoria ya sea por tener el montón de ir todo el camino a la parte inferior, o tienen la pila de ir todo el camino hasta la cima, o que tengan el heap y la pila reunirse cara a cara. Todos los que puede haber condiciones que hacen que su programa que se quede sin memoria. Así que tenlo en mente. Cuando hablamos de la pila y la pila realmente estamos hablando de la mismo trozo general de la memoria, simplemente diferentes porciones de esa memoria. Entonces, ¿cómo hacemos para que de forma dinámica asignado memoria en el primer lugar? ¿Cómo funciona nuestro programa llegar la memoria como se está ejecutando? Bueno C proporciona una función llamada malloc, asignador de memoria, lo que usted hace una llamada a, y se pasa en cuántos bytes de memoria que desee. Así que si su programa se está ejecutando y quieres un tiempo de ejecución de enteros, es posible que Mallock cuatro bytes de memoria, malloc paréntesis cuatro. Mallock pasará por mirando a través de la pila, porque somos dinámicamente la asignación de memoria, y volverá a usted un puntero a la memoria. No te da que memory-- no da un nombre, que le da un puntero a él. Y por eso otra vez he dicho que es importante que tal vez han visto el video punteros antes de llegar demasiado lejos en esto. Así malloc va a va a devolver un puntero. Si Mallock no puede darle ninguna memoria porque se le han acabado, que voy a dar vuelta un puntero nulo. ¿Te acuerdas de lo que ocurre si tratar de eliminar la referencia a un puntero nulo? Sufrimos un fallo seg, ¿verdad? Eso probablemente no es bueno. Así que cada vez que realice una llamada a malloc que siempre, siempre, que comprobar si el puntero se lo dio vuelta es nulo. Si es así, usted necesita para poner fin a su programa porque si tratas de eliminar la referencia el puntero nulo vas Hubo un fallo de segmentación y su programa es yendo a estrellarse todos modos. Entonces, ¿cómo hacer que estáticamente obtener un número entero? int x. Probablemente nos hemos hecho un montón de veces, ¿verdad? Esto crea una variable llamada X que vive en la pila. ¿Cómo obtenemos dinámicamente un número entero? Int estrellas px equivale malloc 4. O más apropiadamente diríamos int estrellas px igual tamaño malloc de int, sólo para arrojar algo menos números mágicos de todo nuestro programa. Esto va a obtener para nosotros cuatro bytes de memoria de la pila, y el puntero obtenemos de nuevo a él se llama px. Y a continuación, al igual que nosotros hemos hecho previamente nos puede eliminar la referencia a px acceder a esa memoria. ¿Cómo conseguimos un número entero de usuario? Podemos decir int x es igual a llegar int. Eso es bastante sencillo. ¿Qué pasa si queremos crear una matriz de x carrozas que viven en la pila? flotar stack_array-- ese es el nombre de nuestros corchetes array-- x. Eso creará para nosotros un array de x carrozas que viven en la pila. Podemos crear una matriz de carrozas que vive en el montón, también. La sintaxis puede parecer un poco más engorroso, pero podemos decir flotador heap_array estrellas es igual tiempos malloc x el tamaño del flotador. Necesito espacio suficiente para almacenar x valores de punto flotante. Así que digo que necesito 100 carrozas, o 1.000 flotadores. Así que en ese caso sería 400 bytes para 100 carros alegóricos, o 4.000 bytes para 1.000 flotadores, porque cada flotador ocupa cuatro bytes de espacio. Después de hacer esto que puedo utilizar el sintaxis de corchete en heap_array. Del mismo modo que lo haría en stack_array, I puede acceder a sus elementos individualmente utilizando heap_array cero, uno heap_array. Pero recordar la razón por la que podemos hacer eso se debe a que el nombre de una matriz en C es realmente un puntero a primer elemento de la matriz. Así que el hecho de que estamos declarando una variedad de carrozas en la pila aquí en realidad es un poco engañoso. Realmente estamos en el segunda línea de código que hay También la creación de un puntero a un trozo de memoria que a continuación hacemos un poco de trabajo con. Aquí está el gran problema con asignada dinámicamente memoria, sin embargo, y es por eso que es muy importante desarrollar algunos buenos hábitos cuando se trabaja con él. A diferencia estáticamente declarada la memoria, la memoria no se devuelve automáticamente al sistema cuando su función se hace. Así que si tenemos principal, y principal llama a una función f, cuando f acabados lo que está haciendo y devuelve el control del programa volver al principal, toda la memoria que f utilizada se devuelve. Se puede utilizar de nuevo por algún otro programa, o alguna otra función que se vuelve a llamar más tarde en la principal. Puede utilizar esa misma memoria otra vez. Si dinámicamente asignar memoria aunque usted tiene que decirle explícitamente la sistema que haya terminado con él. Se va a aferrarse a él para usted, lo que podría conducir a un problema de ustedes corriendo de la memoria. Y, de hecho, a veces nos referimos a esto como una pérdida de memoria. Y a veces estas pérdidas de memoria en realidad puede ser muy devastador para el rendimiento del sistema. Si usted es un usuario frecuente de Internet podría utilizar ciertos navegadores web, y no voy a dar nombres aquí, pero hay algunos navegadores web por ahí que son conocidos por tener realmente pérdidas de memoria que no te fijas. Y si usted deja su navegador abierta para un período muy largo de tiempo, día y días, o semanas, a veces podría darse cuenta de que su sistema está funcionando muy, muy lentamente. Y la razón de ello es que el navegador ha asignado memoria, pero entonces no le dijo al sistema que se hace con ella. Y por lo que deja menos memoria disponible para todos sus otros programas a tener que compartir, porque eres leaking-- que navegador web programa tiene una fuga de memoria. ¿Cómo nos damos memoria de nuevo cuando hayamos terminado con ella? Bueno, afortunadamente, es un manera muy fácil de hacerlo. Nos liberamos ella. Hay una función llamada gratuita, acepta un puntero a la memoria, y estamos listo para salir. Así que digamos que estamos en el medio de nuestro programa, queremos malloc 50 caracteres. Queremos malloc una matriz que puede capaz de contener 50 caracteres. Y cuando lleguemos a un puntero de nuevo a que, el nombre de ese puntero es la palabra. Hacemos lo que somos va a hacer con la palabra, y luego, cuando estamos hecho que sólo liberamos ella. Y ahora que hemos vuelto los 50 bytes de la memoria de vuelta al sistema. Alguna otra función puede utilizarlos. Nosotros no tenemos que preocuparnos por sufrir una pérdida de memoria, ya hemos liberado palabra. Hemos dado a la memoria de nuevo, así que hemos terminado de trabajar con él. Así que hay tres reglas de oro que deben debe tenerse en cuenta siempre que esté asignación dinámica de memoria con malloc. Cada bloque de memoria que que malloc debe ser liberado antes de su programa acaba de correr. Ahora, de nuevo, en el aparato o en el IDE este tipo de pasa para usted de todos modos cuando usted-- esto va a suceder de todos modos cuando se termina el programa, toda la memoria se dará a conocer. Pero es en general buena codificación la práctica de siempre, cuando haya terminado, liberar lo que has mallocd. Dicho esto, las únicas cosas que tienes mallocd debe ser liberado. Si se declara estáticamente un número entero, int x punto y coma, que vive en la pila, que no entonces querer liberar x. Así únicas cosas que usted ha mallocd debe ser liberado. Y por último, no hacer algo libre dos veces. Eso puede conducir a otra situación extraña. Así que todo lo que tienes mallocd tiene que ser liberado. Sólo las cosas que usted ha malloc debe ser liberado. Y no hacer algo libre dos veces. Así que vamos a ir a través de un ejemplo aquí de lo que algunos asignan dinámicamente la memoria podría ser similar mixta en con un poco de memoria estática. ¿Qué podría pasar aquí? Vea si usted puede seguir a lo largo y ¿adivinen qué es va a ocurrir a medida que avanzamos a través de todas estas líneas de código. Por eso decimos int m. ¿Qué pasa aquí? Bueno, esto es bastante sencillo. Creo una variable entera llamada m. Coloreo es verde, porque ese es el color que utilizo cuando estoy hablando sobre variables enteras. Es una caja. Se llama m, y se puede almacenar enteros en el interior de la misma. ¿Y si luego decir int estrellas una? Bueno, eso es bastante similar. Estoy creando una caja llamada. Es capaz de celebración int estrellas, los punteros a enteros. Así que estoy colorear de verde-ish también. Sé que tiene algo que ver con un entero, pero ella misma no es un entero. Pero es más o menos la misma idea. He creado una caja. Ambos derecho ahora viven en la pila. Yo les he dado dos nombres. int estrellas b es igual tamaño malloc de int. Éste podría ser un poco difícil. Tome un segundo y pensar en lo que sería esperar que suceda en este diagrama. int estrellas b es igual tamaño malloc de int. Bueno, esto no se limita a crear una caja. En realidad, esto crea dos cajas. Y se vincula, también establece un punto en una relación. Hemos asignado un bloque de la memoria en el montón. Observe que el cuadro de arriba a la derecha allí no tiene un nombre. Nos mallocd ella. Existe en el montón. Pero b tiene un nombre. Es una variable puntero llamado b. Que vive en la pila. Así que es un pedazo de la memoria que apunta a otro. b contiene la dirección de ese bloque de memoria. No tiene un nombre de lo contrario. Pero apunta a la misma. Así que cuando decimos int estrellas b es igual a tamaño malloc de int, que allí mismo, esa flecha que apareció en la lado derecho hay, toda esa cosa, Voy a tener que parezca de nuevo, es lo que sucede. Todo eso sucede en esa sola línea de código. Ahora vamos a llegar poco más sencillo de nuevo. un signo igual a m. ¿Recuerdas lo que es un es igual signo m es? Bueno, eso es una obtiene la dirección del m. O dicho más esquemática, unos puntos a m. una es igual a b. Aceptar así que aquí está otro. A es igual a b. Qué va a pasar el diagrama de este tiempo? Bueno recordar que el trabaja el operador de asignación asignando el valor en el derecho a el valor a la izquierda. Así que en lugar de un señalador para m, una empresa apunta al mismo lugar que los puntos b. un no apunta a B, A señala los puntos donde b. Si una punta a B que haría han sido un símbolo de unión es igual a b. Pero en lugar de una es igual a b justo significa que ayb son ahora apuntando a la misma dirección, porque en el interior de b es sólo una dirección. Y ahora en el interior de un es la misma dirección. m es igual a 10, probablemente el cosa más sencilla que hemos hecho en un poco. Ponga el 10 en el cuadro. Estrella b es igual a m más 2, recuerdan desde nuestra punteros de video lo que la estrella b significa. Vamos a eliminar la referencia b y put algún valor en esa posición de memoria. En este caso 12. Así que cuando nos dereference un punto de Recordemos que sólo viajamos por la flecha. O dicho de otra manera, ir a esa dirección de memoria y manipulamos de alguna manera. Ponemos algún valor en allí. En este caso la estrella b es igual a m más 2 es sólo ir a la variable apuntada por b, ir a la memoria apuntada por b, y poner m más 2 ahí, 12. Ahora libero b. ¿Qué sucede cuando gratuito B? Recuerde lo que dije medios libres. ¿Qué estoy diciendo cuando me libero b? Ya he terminado de trabajar con él, ¿no? Yo esencialmente renunciar a la memoria. Me doy vuelta al sistema. No necesito más esto es lo que les estoy diciendo, ¿de acuerdo? Ahora bien, si yo digo una estrella es igual a 11 es probable que pueda ya decirle que algo malo que va a pasar aquí, ¿verdad? Y de hecho si lo intentara que probablemente sufriría un fallo de segmentación. Porque ahora, aunque previamente que trozo de memoria era algo que tenía el acceso a, en este punto ahora estoy acceder a la memoria que no es legal para que tenga acceso. Y a medida que probablemente recordar, cuando accedemos a la memoria que no se supone que tocar, esa es la causa más común de una segmentación culpa. Y así mi programa se estrellaría si trataba de hacer esto. Así que de nuevo es una buena idea para obtener buena prácticas y los buenos hábitos arraigados cuando se trabaja con malloc y libre, de modo que usted no sufre segmentación fallas, y que se utilizan su asignados dinámicamente memoria de forma responsable. Soy Doug Lloyd esto es CS50.