[REPRODUCCIÓN DE MÚSICA]
>> DAVID J. MALAN: Muy bien.
Esto es CS50.
Y este es el comienzo de la semana 5.
Y como te habrás dado cuenta, algunos de los materiales
es cada vez un poco más compleja, el poco denso.
>> Y es muy fácil, especialmente si usted ha estado en el hábito durante algún tiempo,
estar tratando de garabatear más cualquier cosa que hagamos, estamos diciendo en clase.
Pero se dan cuenta, que no es tal vez el enfoque pedagógico ideales
para el aprendizaje de este tipo de material, y el material de manera más general.
Y así tenemos el placer de anunciar propia Gheng de que CS50
Gong ha comenzado a preparar un conjunto canónico de notas
para el curso, la esperanza de y es que, uno, éstos
no sólo servir como un de referencia y un recurso
para revisar el material y va de vuelta a través de material que pudiera tener
le escapó la primera vez, pero También para que sus cabezas pueden ser más
arriba que abajo, cuando se llega el momento de dar una conferencia,
por lo que es posible que participar más pensativo, como
frente a los más scribbly.
>> Dicho esto, lo que encontrará en el sitio web es documentos como este.
Y fíjense, en la parte superior izquierda, hay no sólo una tabla de contenidos,
sino también los códigos de tiempo que le saltará inmediatamente
a la parte apropiada en el video en línea.
Y lo ha hecho aquí Chang es, esencialmente, documentado
lo que sucedió en este especialmente conferencia.
Y muchas de las conferencias son ya en línea ahora con esta URL.
Y vamos a seguir para publicar el resto de los que a finales de esta semana,
así que aprovechar ese recurso.
>> Así que sin más preámbulos, empezamos a pelar
la capa que ha sido cadena durante algún tiempo.
Y lo dijimos una cadena en realidad es la semana pasada?
Estrellas Así caracteres.
Y la estrella char, así, lo que qué significa esto realmente?
Bueno, todo este tiempo, si hemos sido llamada a una función,
como getString y almacenamiento la llamada de retorno
valor de getString en un variable-- se llama
s tipo string-- hemos estado escribiendo la línea de código que hay allá arriba.
Y es sólo cuando veo a mi escritura magnificada aquí
me doy cuenta de lo atroz que es esto.
>> Sin embargo, vamos a suponer que, en el lado derecho
es, no obstante, una razonable representación de lo que es
estado sucediendo todo esto tiempo con getString.
getString, por supuesto, crear una cadena.
Pero, ¿qué significa esto realmente?
Esto significa que se pone un trozo de de memoria desde el sistema operativo
llamando a una función, llamada malloc.
Pero más sobre esto más adelante.
Y entonces puebla que parte de la memoria
con las letras el usuario tiene escrito en, seguido de, por supuesto,
un carácter nulo, ni la barra invertida cero al final.
>> Mientras tanto, en el lado izquierdo de esta historia, todo este tiempo,
hemos estado declarando una variable, como s.
Y esa variable es lo que ahora se empieza a llamar a un puntero.
No es una caja en cuyo interior ponemos la cadena, Daven, per se,
sino que ponemos en esa plaza caja de la izquierda ¿qué es exactamente?
¿Sí?
>> AUDIENCIA: La dirección de donde se encuentra en la memoria.
>> DAVID J. MALAN: Exactamente.
La dirección de donde Daven se encuentra en la memoria.
Y no en todos Daven se encuentra, per se, sino específicamente la dirección
de qué?
¿Sí?
>> AUDIENCIA: Primer carácter.
>> DAVID J. MALAN: El primer carácter en Daven, que, en este caso,
Me proponía era arbitraria y poco realista 1, Ox1,
que sólo significa la número hexadecimal de 1.
Pero probablemente va al ser un número mucho más grande
que podríamos llamar la con un 0x como un prefijo,
representa un carácter hexadecimal.
Y debido a que no necesitamos saber dónde el resto de los caracteres de Daven
son, por lo que el diseño sencillo decisión que fue hecha hace muchos años?
¿Sí?
>> AUDIENCIA: Backslash 0.
DAVID J. MALAN: Sí, exactamente.
La barra invertida 0 le permite, aunque de tiempo lineal, para atravesar la cadena,
caminar de izquierda a derecha, con un bucle, o un tiempo
lazo, o algo así eso, y determinar, oh, aquí
es el final de esta cadena particular.
Así que con sólo la dirección en el principio de una cadena,
podemos acceder a la totalidad de , porque durante todo este tiempo,
una cadena sólo ha sido una estrella de carbón.
>> Por lo que es sin duda muy bien para seguir utilizando la biblioteca CS50 y esta abstracción,
por así decirlo, pero vamos a comenzar a ver exactamente
lo que ha estado pasando debajo de todo este tiempo.
Así que usted puede recordar este ejemplo, también, de la última vez, comparar 0,
que no compare realidad.
Pero empezamos a resolver esto.
>> Pero como tal vez un refresco, podría yo interesar a alguien
en un elefante rosa hoy, también fabricada por Chang?
¿Y usted delante? [Inaudible].
Vamos arriba.
>> Y mientras tanto, a medida que surgen, vamos a
considerar por un momento lo que Este código fue realmente haciendo.
Se declara dos variables arriba superior, s y t, y llamando getString.
Este no es un programa muy fácil de usar, porque no te dice qué hacer.
Pero vamos a suponer que estamos centrándose en la parte jugosa.
Y entonces lo que hacemos, si s es igual a es igual a t, debe decir printf,
que ha escrito la misma cosa.
Hola.
Cuál es tu nombre?
>> JANELLE: Janelle.
DAVID J. MALAN: Janelle, Encantada de conocerte.
Así que su desafío a la mano para este elefante
es primero nos hagan un dibujo de lo que es está representado en los dos primeros
líneas.
Así que s y t puede ser representado la forma en la pantalla?
Y sólo se puede dibujar con el dedo en esta pantalla grande.
>> Así que hay dos mitades a cada lado de la ecuación.
Así que hay s de la izquierda, y entonces getString a la derecha.
Y luego está el t de la izquierda, y luego getString a la derecha.
Entonces, ¿cómo podríamos empezar un dibujo que
representa lo que está pasando aquí en la memoria, qué le dirías?
Y déjame dejarte explicas lo que estás haciendo sobre la marcha.
>> JANELLE: OK.
Bueno, en primer lugar, que estaría pidiendo a obtener la cadena de entrada.
Y sería almacén-- oh, lo siento.
DAVID J. MALAN: OK.
Bueno.
Y esto se llama, ¿qué?
Oh, OK.
Sigue adelante.
No quise interrumpir.
JANELLE: Lo siento.
Por lo que sería la entrada en la dirección no de-- seguro.
No puedo recordar exactamente el número, pero creo que empezaba con 0.
>> DAVID J. MALAN: Está bien, porque hice los números hacia arriba,
así que no hay respuesta correcta.
>> JANELLE: A partir de la 0 de arco.
>> DAVID J. MALAN: OK, por lo que el elemento 0.
Claro.
>> JANELLE: Y luego, si era como sólo un dos-letter--
>> DAVID J. MALAN: OK, de nuevo a usted.
>> JANELLE: Así que el elemento 0, y a continuación, el elemento 1 o del elemento 2.
DAVID J. MALAN: Y qué pieza de la imagen se le dibujaba en este momento?
La llamada a getString?
O la declaración de s?
>> JANELLE: La declaración de s, creo.
Oh, la getString, porque haría ser introducida en cada uno de [? área. ?]
>> DAVID J. MALAN: Good.
Exactamente.
A pesar de que esto efectivamente devuelve una matriz, el recuerdo,
cuando volvamos una cadena, podemos índice en esa cadena usando 01 y 2.
Técnicamente, estos son probablemente representada por las direcciones individuales,
pero eso está bien.
>> Así que supongamos que, si puedo sólo es rápido remitir a donde lo dejamos
la última vez, si uno de las cuerdas era g a b e,
barra invertida 0, lo cual representa una de gabe de entrada, ¿cómo podríamos representar s ahora?
Si esta es la memoria que es sido devuelto por getString?
>> JANELLE: ¿Sería representado por un arco?
>> DAVID J. MALAN: Por un arco?
Bueno, no.
Digamos, ilustrado, déjame seguir adelante
y proponer que, si esto es s, este es el valor devuelto por getString.
Y que ha dibujado esto como 0, 1, 2, que es perfectamente razonable, porque
puede indexar en la cadena, como tal.
Pero sólo para estar en consonancia con la última vez, déjame ir por delante
y proponer arbitrariamente que este es la dirección 1, esta es la dirección 2,
Esta es la dirección 3, y así sucesivamente.
Y así, sólo para estar súper claro, lo que pasa
ir en s como resultado de ese primera línea de código, qué le dirías?
>> JANELLE: Dirección 1?
>> DAVID J. MALAN: Exactamente.
Así abordar 0x1.
Y mientras tanto, deja que me vaya por delante y duplicarían gran parte de lo que has hecho
y añadir mi propia t aquí.
Si tuviera que escribir gabe de nuevo, un segundo tiempo,
cuando se le solicite con getString, donde, por supuesto, se gabe va a ir?
Bueno, presumably--
>> JANELLE: Al igual que en esta lista?
DAVID J. MALAN: Si.
JANELLE: O es también en las mismas cajas?
DAVID J. MALAN: Déjame propongo, sí, exactamente, por lo que en estas cajas adicionales.
Pero lo que es clave ahora es que, incluso aunque yo he dibujado estos muy cerca
juntos-- 0x1, este se 0x2-- en la realidad,
esto ahora podría ser la dirección 0x10, por ejemplo, y 0x11, y 0x12,
y así sucesivamente.
Y así, si ese es el caso, lo que va a terminar aquí, en t?
>> JANELLE: 0x10?
DAVID J. MALAN: Exactamente.
Así 0x10.
Y ahora, la pregunta final.
Has, por el momento, tuvo que trabajar el más difícil para un elefante hasta el momento.
Por ahora, si me levanto el código de nuevo, cuando lo hago, en la línea tres,
si s es igual a es igual a t, lo que estoy realmente comparando que hemos dibujado aquí?
>> JANELLE: Las dos direcciones?
DAVID J. MALAN: Exactamente.
Así que yo estoy diciendo es S igual igual at?
En otras palabras, es igual 1 igual a 10?
Y, por supuesto, la respuesta obvia ahora es, no.
Y por lo que este programa es en última instancia, va a imprimir lo que, qué le dirías?
>> JANELLE: ¿Sería, que ha escrito la misma cosa?
>> DAVID J. MALAN: Así que si s es 1 y t es de 10?
>> JANELLE: Ha escrito diferentes cosas.
>> DAVID J. MALAN: Exactamente.
Ha escrito diferentes cosas.
Bien.
Así que un aplauso, si pudiéramos, aquí.
[Aplausos]
Eso fue doloroso.
Lo sé.
Muy bien hecho.
Así que ahora vamos a ver si no podemos desmenuzar lo que era la solución.
Y por supuesto, cuando nos fijamos esto-- que ahora voy a represento en green--
hicimos un par de mejoras aquí.
En primer lugar, al igual que una cordura comprobar, estoy consultar primero
si s es igual a nula y t es igual a cero.
Y sólo para ser claros, cuando podría s o t ser nula en código como este?
Cuando pueden s o t ser nulo.
¿Sí?
>> AUDIENCIA: [inaudible].
>> DAVID J. MALAN: Exactamente.
Si la cadena que el usuario tecleado es demasiado largo
para caber en la memoria, o alguna caso esquina extraño como eso,
getString, como veremos, literalmente hoy, en su documentación,
dice que devolverá un valor nulo como un valor especial centinela,
o simplemente una especie de símbolo especial eso significa que algo salió mal.
Así que queremos comprobar si hay que, porque resulta que
que nulo es un valor muy peligroso.
>> A menudo, si usted trata de hacer algo con nula que implica un function-- pasándolo
como entrada, para instance-- esa función podría muy se estrellará y, con ella,
acabar con todo su programa.
Así que esta tercera línea ahora es sólo una cordura comprobar, comprobación de errores, si se quiere.
Eso es un buen hábito ahora para nos metemos en cualquier momento que
tratar de usar un valor que podrían, potencialmente, ser nulo.
>> Ahora, en la cuarta línea de aquí, "Si strcmp (s, t)," bien,
¿cuál es el que se refiere a?
Bueno, dijimos que esto era una manera muy sucinta función llamada para la comparación de cadenas.
Y su propósito en la vida es comparar su primer argumento en contra de ella en segundo lugar,
pero no en términos de sus direcciones, como lo hicimos sin querer un momento
hace con el código rojo, pero en lugar de comparar los dos
cadenas en el humanamente intuitiva mediante la comparación de esta manera, en contra de este,
contra esto, contra esto, y luego se detienen si y cuando uno
o los dos de mis dedos realiza un barra invertida 0.
Strcmp Así que hace años alguien implementadas para poner en práctica para nosotros la funcionalidad
que esperamos nos hubiéramos conseguido sólo por comparación de dos valores simples.
>> Ahora, francamente, no dejo de dibujo todos estos diversos números.
Pero la realidad es, que he sido haciendo éstos para arriba todo el tiempo.
Y así que permítanme simplemente seguir adelante y garabatear estas fuera
para hacer un punto que, al final del día y se mueve hacia adelante,
no estamos realmente va a preocuparse por lo que aborda las cosas son en realidad
en la memoria.
Así que no voy a dibujar estos clases de números mucho más,
Soy sólo un resumen esta distancia un poco más amable con sólo flechas.
>> En otras palabras, si s es un puntero, así, vamos a dibujar es, literalmente,
como un puntero, una flecha apuntando de sí mismo a otra cosa,
y no te preocupes demasiado más sobre las minucias de estas direcciones
que, de nuevo, hice de todos modos.
Pero vamos a ver esas direcciones, a veces, cuando la depuración del código.
>> Ahora mientras tanto, este programa aquí correcciones, por supuesto,
ese problema comparando esas dos cadenas.
Pero nos encontramos con otro problema.
Esta era de la copia programar la última vez,
con lo cual, yo estaba tratando de capitalizar sólo el primer carácter de una cadena.
Pero lo que era el síntoma vimos la última vez cuando
un usuario escribió en un valor, como gabe en minúsculas, para s,
entonces asignamos s en t, como en la tercera línea de allí,
y luego traté de capitalizar t soporte 0?
¿Cuál fue el efecto de la cambiando t soporte 0 aquí?
>> AUDIENCIA: Cambió s.
>> DAVID J. MALAN: Sí, Cambié s, también.
Porque lo que realmente estaba pasando?
Bueno, déjame ver si puedo limpiar esta imagen, como sigue.
>> Si s es, de nuevo, la palabra g, a, b, e, barra invertida, 0 y s
continuaremos dibujo como una caja aquí, pero hay más direcciones.
Vamos a dejar de hacer las cosas.
Vamos a hacer un dibujo para simplificar el mundo.
>> Cuando declaro t con una cuerda t, que crea que parte de la memoria.
Plaza pasa a ser 32 bits en la mayoría de ordenadores.
De hecho, si alguna vez has oído hablar de un ordenador que tiene una arquitectura de 32 bits,
realmente de lujo-hablar, que sólo significa que utiliza direcciones de 32 bits.
Y como una técnica a un lado, si alguna vez se ha preguntado
¿por qué los equipos más antiguos, si realmente tratado de sopa para arriba con una gran cantidad de memoria RAM,
sólo podía tener un máximo de cuatro gigabytes de RAM,
bueno eso es porque, literalmente, su antiguo equipo sólo podía
contar tan alto como 4 mil millones, 4 mil millones de bytes,
porque estaba usando 32 bits números de direcciones.
>> Pero en cualquier caso, en este ejemplo, de historia mucho más simple.
t es sólo otro puntero, o realmente una estrella char, también conocido como cadena.
¿Y cómo es lo que quiero para actualizar la imagen ahora con la segunda línea de código,
después del punto, punto, punto?
Cuando hago cadena t es igual a s punto y coma, ¿Cómo cambia esta foto?
¿Sí?
>> AUDIENCIA: [inaudible].
>> DAVID J. MALAN: Si.
Exactamente.
Acabo de poner una flecha de la t caja a la misma dirección,
la misma primera letra dio.
O técnicamente, si esto chico estaban todavía en 0x1,
es como si tuviera 0x1 0x1 aquí y aquí.
Pero, de nuevo, a quién le importa acerca de las direcciones?
Es sólo la idea de que ahora importa.
Así que esto es lo que está pasando aquí.
Así que por supuesto, si lo hace t soporte 0, que es la notación de matriz,
supuesto-- y, francamente, parece que hay una gran variedad aquí,
pero ahora hay una cosa extraña.
Debes saber que el lenguaje de programación, C, le ofrece esta función,
por lo que, incluso si t es un puntero, o s es un puntero,
puede seguir utilizando ese familiar, corchete cómodo
notación para ir al primer elemento, o el segundo elemento, o cualquier elemento
que ese puntero está apuntando a, ya que, presumiblemente, se
es, como en este caso, apuntando en algún matriz.
>> Entonces, ¿cómo podemos solucionar este problema?
Francamente, aquí es donde se consiguió un poco abrumador a primera vista.
Pero aquí es una versión nueva y mejorada.
>> Así que primero, me estoy poniendo deshacerse de la biblioteca CS50,
sólo para exponer que s es de hecho una estrella char, sólo un sinónimo.
Y t es también una estrella de carbón.
Pero lo que está sucediendo en el lado derecho de esa línea
donde t se asigna un valor?
>> ¿Qué es malloc?
¿Qué se strlen?
¿Qué es sizeof (char)?
¿Por qué demonios hace esto mirada tan compleja línea?
¿Qué hace a un alto nivel?
¿Qué se almacena en t?
¿Sí?
AUDIENCIA: Es la asignación de un cierta cantidad de espacio de memoria.
Es para almacenar, supongo, cartas [inaudible].
>> DAVID J. MALAN: Perfect.
Perfect.
Es la asignación de un determinado cantidad de espacio de memoria
para almacenar, presumiblemente, cartas futuras.
Y en particular, malloc por lo tanto, está regresando qué?
>> AUDIENCIA: Devolución de la [inaudible]?
DAVID J. MALAN: Exactamente.
Volviendo la dirección de esa memoria, que es una forma elegante de decir,
devuelve la dirección de la primer byte de esa memoria.
La responsabilidad recae en mí recordar la cantidad de memoria que en realidad
asignado o solicitado para malloc.
>> Ahora, ¿cuánto es eso?
Bueno, a pesar de que no hay un montón de paréntesis aquí,
malloc toma un solo argumento.
Y estoy especificando strlen de s, por lo que dan me tantos bytes como los hay en s,
pero agrega uno.
¿Por qué?
¿Sí?
>> AUDIENCIA: La barra invertida 0.
DAVID J. MALAN: Exactamente.
Tenemos que hacer un poco de limpieza.
Así que porque hay una barra invertida 0, será mejor recuerdo.
De lo contrario, vamos para crear una cadena que
no tiene que terminador especial.
>> Mientras tanto, sólo para estar súper anal, tengo sizeof (char),
por si acaso alguien se queda mi código no en el aparato CS50,
pero tal vez un equipo diferente en total, donde caracteres
son un byte, por convención, pero dos bytes, o algo más grande que eso.
Es sólo que ser súper, súper reacio a errores.
A pesar de que, en realidad, es más probable que va a ser un 1.
>> Ahora, mientras tanto, sigo adelante y copio el cuerda, t soporte i es igual a t soporte s.
Y voy a aplazar hasta la semana del pasado código fuente para ver lo que está pasando.
Pero el punto clave, y la razón por la que poner el código ahora en verde,
se debe a que la última línea, t soporte 0 es igual toupper,
tiene el efecto de capitalización qué cadena?
t y / o s?
Esa última línea de código.
>> Justo t, porque lo que es pasado este tiempo,
si puedo deshacer un poco el último paso, Lo que pasa es, cuando llamo a malloc,
Yo esencialmente consigo un trozo de memoria que es el mismo tamaño que el original,
porque esa es la aritmética que hice.
Estoy almacenando en t la dirección de ese trozo de memoria.
A pesar de que este se ve bien y bonita, agradable y en blanco,
la realidad es que hay, lo que vamos a seguir llamando, los valores de basura aquí.
Ese trozo de memoria podría muy así se han usado antes,
unos segundos, hace unos minutos.
Así que no podría absolutamente ser números o cartas allí, sólo por accidente.
Pero no son válidas, hasta que yo pueblan este trozo de memoria
con caracteres reales, como yo hacer en ese bucle allí.
Bien?
>> Así que ahora, el punto culminante de estos tres ejemplos
que fueron aparentemente roto la última vez, este ejemplo de intercambio, esta función
trabajado en el sentido que cambió a y b.
Pero no funcionó en lo otro sentido?
¿Sí?
>> AUDIENCIA: [inaudible].
>> DAVID J. MALAN: Exactamente.
Si tuviera que llamar a esta función de otro-- por ejemplo,
de una función como principal, donde Tengo una variable, x e y, como yo
lo hizo la semana pasada, el mismo código, y paso en x e y
al intercambio, y luego llamar a Swap-- esto, por supuesto, es la versión correcta
es lo que estamos a punto de ver-- no funcionó.
Entonces, ¿cuál es la solución?
>> Bueno, por lo que sólo para estar claro, déjame ir por delante
y-- dame un segundo aquí, y ver si te puedo mostrar la última, que
será en-- vamos a ver si puedo encontrar esta verdadera Aceptar fast--, [inaudible].
Bueno, ahí está.
Así que ignora los comandos Sólo estoy escribiendo.
Quiero que se recupere en el último minuto un ejemplo
de la última vez, que ahora se llama no Swap.
>> Así que no es de intercambio donde lo dejamos la última vez,
por lo cual, I inicializa x e y de 1 a 2.
Entonces yo llamo Swap, que pasa en 1 y 2.
Y entonces esta función trabajado en algún sentido,
pero no tenía permanente efectuar en xe y.
Así que la pregunta en cuestión es, ¿cómo ahora es lo que realmente solucione este problema?
¿Cuál es la solución a la mano?
>> Bueno, en swap.c, que es nuevo hoy, cuenta un par de diferencias.
x e y son el mismo.
Pero lo que es claramente diferente en la línea 25?
¿Qué hay de nuevo allí, si usted recuerda lo que parecía hace un segundo?
>> AUDIENCIA: [inaudible].
>> DAVID J. MALAN: Si.
Así que los símbolos de unión son una nueva pieza de la sintaxis, no sólo en este programa,
sino también de forma más general en CS50.
Hasta la fecha, no creo hemos visto algunos ejemplos
o realmente hablado de ellos en cualquier detalle, que no sea, tal vez, de forma preventiva
en sección, un símbolo de unión así.
Bueno, resulta que signo es uno de las últimas piezas de nueva sintaxis
vamos a aprender.
Lo único que significa es la dirección de alguna variable.
¿En qué dirección lo hace x viven?
Pero, ¿qué dirección y qué viven?
Porque si el problema fundamental antes
se se fueron pasando que x e y como copias, lo que realmente queremos hacer
se proporcionará Intercambio con como un tesoro mapa que conduce a donde x e y en realidad
son en la memoria RAM, de forma que Intercambiar puede seguir ese mapa
e ir a donde quiera x ó y marca el lugar y cambiar los valores actuales 1 y 2
Ya está.
>> Así Intercambiar tiene que cambiar un poco demasiado.
Y a primera vista, esto podría parecer un poco similar a la estrella de carbón.
Y de hecho lo es.
Así que a es un puntero a qué tipo de datos, basado en esta porción resaltada?
Así que es un int.
>> Así que una ya no es un int, que es la dirección de un int.
Y de manera similar, b ahora va es la dirección de un int.
Así que cuando doy la palabra de intercambio de principal, Yo no voy a dar Intercambio 1 y 2.
Voy a darle como Ox-algo y Ox-algo,
dos direcciones que conduzcan Cambiar para sus ubicaciones reales
en la memoria de mi computadora.
>> Así que ahora, mi implementación restante tiene que cambiar un poco.
¿Cuál es obviamente diferente ahora en estas tres líneas de código?
Hay estas malditas todas las estrellas el lugar, ¿de acuerdo?
Entonces, ¿qué está pasando aquí?
¿Sí?
>> AUDIENCIA: Obviamente es [inaudible].
>> DAVID J. MALAN: Exactamente.
Así que en este contexto-- y esto no era la mejor decisión de diseño, hay que reconocerlo,
hace años.
En este contexto, donde sólo hay una estrella,
y usted no tiene un tipo de datos, como int, inmediatamente a la izquierda,
en cambio usted tiene un signo igual, con claridad, en este contexto, cuando dices protagonizar una,
eso significa ir a la dirección que está en una.
Siga el mapa del tesoro, por así decirlo.
>> Y mientras tanto, en la línea 37, que significa lo mismo.
Vaya a la dirección de una, y poner lo que hay?
Todo lo que es en la ubicación que especifica b.
En otras palabras, vaya a b.
Obtener ese valor.
Ir a una y, por la igualdad firmar, el operador de asignación,
puesto que el valor allí.
>> Del mismo modo, int temp es sólo un int.
Nada tiene que cambiar de temp.
Es sólo un vaso de repuesto de Annenberg un poco de leche o jugo de naranja.
Pero yo necesito decir, vaya a b.
Ir a ese destino y poner el valor en temp allí.
Entonces, ¿qué está pasando entonces?
Cuando en realidad llamo Cambie este momento, si esta primera bandeja aquí representa Main,
esta segunda bandeja representa Swap, cuando Paso ampersand x y símbolo de unión y
desde Principal a swap, para ser claros, ¿qué es esto pila marco de recepción?
¿Sí?
>> AUDIENCIA: [inaudible].
DAVID J. MALAN: Exactamente.
La dirección de la dirección de x y de y.
Y usted puede pensar en estos como direcciones postales.
33 Oxford Street y 35 Oxford Street, y usted
desee mover los dos edificios que se encuentran en esos lugares.
>> Es una especie de una idea ridícula, pero eso es todo lo que queremos decir con la dirección.
¿Dónde en el mundo puede a encontrar esos dos enteros?
¿Dónde en el mundo se puede encontrar a los dos edificios?
Así que si, finalmente, después de tanto tiempo me entrar en el código fuente de hoy y compilar
Intercambiar y correr ./swap, finalmente, para el primera vez que hacemos realmente para ver que
mis valores tienen a la verdad ha intercambiado con éxito.
Y ahora, incluso podemos tener nota de esta, digamos, en gdb.
>> Así que déjame ir en el mismo archivo.
Déjame ir por delante y correr gdb de ./swap.
Y ahora, en el Swap, voy a ir adelante y establecer un punto de ruptura en principal.
Y ahora me voy a ir adelante y ejecutar el programa.
Y ahora vemos mi código detenido en esa línea.
>> Si sigo adelante e imprimir x, lo que debo ver aquí?
Es una pregunta.
Dilo de nuevo?
>> AUDIENCIA: [inaudible].
>> DAVID J. MALAN: Así números al azar, tal vez.
Tal vez tengo suerte, y es agradable y simple, como 0.
Pero tal vez es un poco de números aleatorios.
En este caso, tuve suerte.
Es sólo pasa a ser 0.
Pero sí es suerte, porque no hasta que
escriba al lado y luego print x tiene que línea de código, la línea 19, ha ejecutado.
>> Mientras tanto, si escribo la próxima vez, y Ahora imprimir y, voy a ver 2.
Ahora, si escribo siguiente, que va a ser un poco confuso, porque ahora,
el printf va a aparecer en la pantalla, como lo hizo. x es 1.
>> Vamos a hacer esto de nuevo.
Y ahora, aquí es donde las cosas se ponen interesantes.
Antes de que yo llamo Intercambiar o incluso paso en ella, vamos a echar un pequeño vistazo.
x es, de nuevo, 1.
Y es, por supuesto, la cordura rápida comprobar, 2, por lo que no es difícil que hay.
Pero lo que es signo x?
Respuesta, es una especie de funky busca.
Pero el int estrellas en paréntesis es sólo forma de decir esto del PIB es una dirección.
No es un int, que es un puntero a un int, o también conocida como una dirección.
>> ¿Qué es esta locura?
Nunca hemos visto algo tan así antes.
Así que esta es la dirección en mi equipo de recuerdo de donde x pasa a vivir.
Es Ox-algo.
Y esto es, francamente, ¿por qué He empezado a dibujar flechas,
en lugar de números, ya que realmente se preocupa
que su int se encuentra en un determinado dirección que es tan grande.
Pero bffff0c4, estos son todos de hecho dígitos hexadecimales,
que son de 0 a f.
>> Así que no vamos a insistir demasiado mucho de lo que son esas cosas.
Pero si imprimo y, por supuesto, veo 2.
Pero ampersand y, veo esta dirección.
Y fíjense, para los curiosos, ¿Qué distancia separa x e y?
Puede pasar por alto la mayor parte de la dirección.
Cuatro bytes.
Y eso es consistente con nuestra antes afirmar que lo grande es un int?
Cuatro bytes.
Así que parece que la guarnición de todo para arriba muy bien, como era de esperar, en la memoria.
>> Así que ahora, vamos a avanzar rápidamente hasta el final de esta historia.
Vamos a seguir adelante y escriba paso, sumergirse en la función Swap.
Ahora note, si escribo una, es idéntica a la dirección de x.
Si el tipo B, que es idéntica a la dirección de y.
Entonces, ¿qué debo ver si dicen, vaya a la dirección de un?
Así imprimir protagonizar una.
Así estrella significa ir allí, en este contexto.
Ampersand significa lo que es la dirección de.
Así estrella un medio 1.
Y print star b me da 2.
>> Y déjame asumo, por el momento, que al menos el código que
procede a ejecutar puede ser ahora motivado a través de esa manera.
Pero nos volveremos a visitar esta idea en poco tiempo.
Así que esta versión de Intercambio ahora es correcta y permite
nos cambiamos a este tipo de datos en particular.
>> Así que cualquier pregunta entonces Swap?
Por estrella?
En la dirección de?
Y verás, con problemas 4, clase de,
pero problemas 5, sin duda, cómo se cosas son útiles y obtener mucho más
cómodo con ellos, como resultado.
Cualquier cosa en absoluto?
Bien.
Así malloc es, de nuevo, esta función que sólo asigna memoria, la memoria
la asignación.
¿Y por qué es esto útil?
Bueno, todo este tiempo, usted ha estado usando malloc.
Si se tiene en cuenta ahora cómo getString obras, presumiblemente, es
estado pidiendo a alguien por un trozo de la memoria, en cualquier momento el usuario escribe una cadena
en, ya que sin duda no sabía, ya que el personal CS50,
lo grande que esas cadenas que los humanos van a escribir podría ser.
>> Así que vamos a, por primera vez, empiezan a Pele cómo funciona la biblioteca CS50,
por medio de un par de ejemplos que nos llevará allí.
Así que si abro gedit y abrir scanf 0,
vamos a ver el siguiente código.
Scanf 0, disponible en el sitio web para hoy en día, tiene relativamente pocas líneas de código
aquí, 14 a través de 20.
Y vamos a ver lo que está haciendo.
Se declara un int, llamado x.
Dice algo así como: número por favor.
Y ahora dice, scanf% i, y x.
Así que hay un montón de cosas nuevas allí.
>> Pero scanf, que tipo de se pueda imaginar de como lo contrario de printf.
printf, por supuesto, se imprime en la pantalla.
tipo scanf de exploraciones desde el usuario de teclado algo que él o ella ha escrito.
>> % I es igual que printf.
Esto significa esperar que el usuario escriba un int.
Y ahora, ¿por qué crees que podría pasar scanf y x?
Si el propósito en la vida de scanf es conseguir algo del usuario,
¿cuál es el significado de pasarlo, y x, ahora?
¿Sí?
>> AUDIENCIA: [inaudible].
DAVID J. MALAN: Exactamente.
Lo que yo, el ser humano, escribo en mi entrada va a ser salvo en ese lugar.
No es suficiente, recordemos, a sólo Aconteció en x, porque hemos visto ya,
cada vez que pasan sólo una variable prima, como un int, para alguna otra función,
Seguro, puede cambiar eso variable, pero no de forma permanente.
No puede tener un efecto sobre Principal.
Sólo puede cambiar su propia copia local.
Pero si, en cambio, no lo hace dame el int real,
pero usted me da direcciones a que int, ahora, siendo scanf,
sin duda, puedo seguir ese abordar y poner un número no
por lo que tiene acceso a él también.
>> Así que cuando ejecuto este programa, vamos a ver.
Hacer scanf 0 punto slash, scanf 0.
Y si ahora estoy escribiendo un número como 50, gracias por el 50.
Si ahora escribo un número como 1 negativo, por lo negativo 1.
Ahora estoy escribiendo un número como 1.5, hm.
¿Por qué mi programa me ignoran?
Bueno, porque simplemente, le dije que esperar sólo un int.
Bien.
Así que esa es una versión de este.
Vamos a tomar las cosas a un nivel superior y proponen que esto no es bueno.
Y aquí radica un ejemplo muy sencillo de cómo podemos empezar a escribir código
que otras personas puedan explotar o comprometer al hacer cosas malas.
Así que la línea 16, tan similar en espíritu de antes,
pero no voy a declararlo int este momento.
Estoy declarando que la estrella char, también conocido como cadena.
>> Pero, ¿qué significa esto realmente?
Así que si no especifico una address-- y Estoy llamando de manera arbitraria, tampón,
pero pude llamo es, para ser simple-- y luego hago esto, explico a mí,
si pudiera, basado en el anterior lógica, lo que está haciendo scanf en la línea 18,
si s pase% y tampón, que es la dirección?
¿Qué es scanf, si se aplica el exactamente la misma lógica que la versión 0,
va a tratar de hacer aquí, cuando el usuario escribe algo en?
¿Sí?
>> AUDIENCIA: [inaudible].
>> DAVID J. MALAN: Exactamente.
Scanf, por la lógica anterior, se va a tomar la cadena
que el mecanografiada humana en-- ahora es una cadena,
no es un número, es de suponer, si él o ella cooperates--
y que va a tratar de poner ese cadena en la memoria en cualquier dirección
búfer especifica.
Y esto es muy bueno, porque búfer es de hecho la intención de ser una dirección.
>> Pero yo sostengo este programa está libre de errores en un manera muy grave, porque ¿qué valor tiene
amortiguar de forma predeterminada?
¿Qué he inicializado en?
Lo trozo de memoria?
Yo no tengo, ¿no?
>> Así que a pesar de que ha asignado un estrella de carbón que ya no se llama s,
se llama en lugar, por lo buffer-- vamos a dibujar el nombre de la variable
ahora como buffer-- si no tengo getString llamada o malloc aquí,
eso significa efectivamente que tampón es sólo un valor de basura.
>> Ahora, ¿qué significa eso?
Significa que yo he dicho scanf esperar una cadena del usuario.
¿Y sabes qué?
Sea lo que está apuntando a-- y dibujo signo de interrogación,
pero en realidad, que va a ser algo así como Ox1, 2, 3, ¿no?
Es cierto valor falso que sólo pasa a estar allí desde antes.
Así que dicho de otra manera, es como si tampón es sólo
que apunta a algo en la memoria.
No tengo ni idea de qué.
>> Así que si escribo en gabe ahora, va para tratar de poner g-a-b-e / 0 no.
Pero, ¿quién sabe lo que es eso?
Y en el pasado, cualquier tiempo hemos tratado de tocar
memoria que no le pertenece a nosotros, ¿qué ha sucedido?
O casi siempre.
Fallo de segmentación, ¿verdad?
>> Esta flecha, no tengo ni idea de dónde es señalando. es sólo un valor aleatorio.
Y por supuesto, si usted interpreta un valor aleatorio como una dirección,
usted va a ir a algún destino al azar.
Así gabe podría efectivamente accidente mi programa en este caso aquí.
>> Entonces, ¿qué podemos hacer eso es casi tan malo?
Considere esta tercera y último ejemplo de scanf.
Esta versión es mejor en qué sentido?
Si se siente cómodo con el problema anterior, esto es mejor.
¿Por qué?
>> AUDIENCIA: [inaudible].
DAVID J. MALAN: Good.
Así que este caso de la línea 16 es mejor, en el sentido
que estamos explícitamente la asignación de una cierta memoria.
No estamos usando malloc, estamos usando la semana 2
enfoque de simplemente declarar una matriz.
Y hemos dicho antes que una cadena es sólo un conjunto de caracteres,
así que esto es totalmente legítimo.
Pero es, por supuesto, como nota, tamaño fijo, 16.
>> Así que este programa es totalmente seguro, si escribo
en las cadenas de un personaje, de dos caracteres cadenas, 15 cadenas de caracteres.
Pero tan pronto como me pongo a escribir 16, 17, 18, 1000, cadenas de caracteres
donde está esa cadena va a terminar?
Se va a acabar en parte aquí.
Pero entonces, ¿quién sabe qué más está más allá de las fronteras
de esta serie en particular?
>> Es como si yo tengo declarado 16 cajas aquí.
Así que en lugar de sacar los 16, vamos a sólo pretendo que he dibujado 16.
Pero si entonces trato de leer un string eso es mucho más largo, como 50 caracteres,
Voy a empezar a poner a, b, c, d, x, y, z.
Y esto es, presumiblemente, algún otro segmento de memoria
que, de nuevo, podría causar mi programa se bloquee,
porque yo no he pedido nada más que 16 bytes.
>> Así que a quién le importa?
Bueno, aquí está la biblioteca CS50.
Y la mayoría de esto es sólo como instrucciones de arriba.
La biblioteca CS50, todo este tiempo, ha tenido esta línea en la línea 52.
Hemos visto typedef, o verá typedef
en conjunto de procesadores 4, que sólo crea una Sinónimo cual estrella carbón puede ser más
referencia simplemente como cadena.
Así que este es uno de los pocas ruedas de entrenamiento
hemos utilizado secretamente debajo de la capucha.
>> Mientras tanto, aquí está la función getchar.
Ahora, aparentemente, no hay cuerpo para ello.
Y de hecho, si sigo desplazamiento, no lo sé en realidad
ver las implementaciones de estas funciones.
Como una comprobación de validez, ¿por qué es eso?
>> AUDIENCIA: [inaudible].
DAVID J. MALAN: Si.
Así que este es el archivo de encabezado.
Y los archivos de cabecera contienen prototipos, además de algunas otras cosas, al parecer,
como typedefs.
Pero en CS50.c, que hemos Nunca le ha dado absoluta,
pero ha sido en el aparato CS50 todo esta vez, en el fondo de sus carpetas,
cuenta de que hay un conjunto montón de funciones aquí.
>> De hecho, vamos a desplazarse hacia abajo.
Vamos a ignorar la mayoría de ellos, por ahora.
Pero desplácese hacia abajo para getInt y vea cómo funciona getInt.
Así que aquí es getInt.
Y si alguna vez realmente importaba cómo llegar int funciona, aquí está su documentación.
Y entre las cosas que dice es lo que dice
lo que los rangos de valores que pueden volver.
Es esencialmente negativo 2000000000 a positivo 2 mil millones, más o menos.
>> Y resulta que, todo esto tiempo, a pesar de que nunca hemos
había que encontrarlo, si algo sale mal,
resulta que todo este tiempo, getInt tiene
ha de devolver un especial constante, no nulo,
sino más bien INT_MAX, que es convención a sólo un programador.
Esto significa aquí es un valor especial.
Asegúrese de comprobar esto, simplemente en caso de que algo va mal.
Pero nunca hemos molestado con que hasta la fecha,
porque, de nuevo, este se entiende para simplificar.
>> Pero, ¿cómo conseguir getInt implementado?
Bueno, uno, que no tiene argumentos.
Sabemos que.
Devuelve un int.
Sabemos que.
Así que, ¿cómo funciona debajo de la capucha?
>> Así que hay al parecer un infinito lazo, al menos la apariencia de uno.
Nótese que estamos usando getString.
Así que eso es interesante. getInt llama nuestra propia función, getString.
Y ahora, ¿podría ser este el caso?
¿Por qué estoy siendo defensiva aquí en línea de 165?
¿Qué podría pasar en línea 164, para ser claros?
Es la misma respuesta que antes.
Podría simplemente estar fuera de la memoria.
Algo va mal con getString, tenemos que ser capaces de manejar eso.
Y la razón por la que no vuelve nula es que, técnicamente, es un puntero nulo.
getInt tiene que devolver un int.
Así que he arbitrariamente decidido, en esencia,
que 2 mil millones, más o menos, va ser un valor especial que nunca puede
en realidad llegar desde el usuario.
Es sólo el valor que yo voy perder para representar un código de error.
>> Así que ahora, las cosas se ponen un poco de fantasía.
Y no es exactamente la misma función como antes, pero es muy similar.
Entonces noto, declaro aquí, en línea 172, tanto en un int n y un char c.
Y entonces yo uso esta línea cobarde, sscanf, lo que resulta
no analiza una cadena desde el teclado.
Se destaca una cadena existente que el usuario ya ha tecleado.
Así que ya llamé getString, que significa que tengo una cadena en la memoria.
sscanf es lo que se llamar a una función de análisis.
Se ve en la cadena que he tecleado, carácter por carácter,
y hace algo útil.
Esa cadena se almacena en línea.
Y sé que sólo por ir una copia de seguridad aquí y decir, oh, OK,
Llamé a no s esta vez, pero la línea.
>> Y ahora esto es un poco diferente.
Pero esto significa, efectivamente, por razones vamos un poco agitamos nuestras manos en la actualidad,
que estamos comprobando a ver si el usuario escribió en
y int y tal vez otro carácter.
Si el usuario escribió en un int, es va a almacenar en n, porque soy
la aprobación de esta por la dirección, el nuevo truco que hemos visto hoy.
Si el usuario también escribe como en 123x, que x
se va a terminar un carta de carácter c.
>> Ahora resulta que sscanf me dirán, inteligente,
cuántos diferentes variables se sscanf éxito capaz de llenar.
Así por esta lógica, si la función Estoy de ejecución es getInt,
pero yo estoy comprobando, potencialmente, para el usuario
haber escrito en un int seguido por otra cosa,
¿Qué quiero de sscanf valor de retorno de verdad que sea?
Si el propósito es conseguir sólo un int del usuario?
>> Así que si sscanf devoluciones 2, ¿qué significa eso?
El usuario escribió en algo así como, literalmente,
123x, que es una tontería.
Es una condición de error, y Quiero comprobar por eso.
>> Así que si el usuario escribe esto en, por esta lógica, lo que hace sscanf volver,
Qué le dirías?
Así que va a devolver 2, porque el 123 va a ir aquí,
y la x va a terminar aquí.
Pero yo no quiero que la x para conseguir lleno.
Quiero sscanf sólo para tener éxito en llenar la primera de sus variables.
Y por eso es que yo Quiero sscanf para volver 1.
>> Y si esto es un poco más de la cabeza por el momento, eso es totalmente bien.
Darse cuenta sin embargo, que uno de los valores de getInt y getString
es que nosotros estamos haciendo una diablos de un gran cantidad de comprobación de errores como éste, así
que, hasta la fecha, usted puede casi escribir nada en su teclado,
y vamos a atraparlo.
Y sin duda, la personal, definitivamente no lo hará
ser la fuente de un error en su programa, porque estamos a la defensiva
la comprobación de todos los estúpidos cosas que un usuario podría hacer,
como escribir una cadena, cuando realmente quería int.
Así que para ahora-- vendremos de nuevo a esto antes long--
pero todo este tiempo, getString y getInt tienen
estado por debajo de la campana, con este idea básica de direcciones de memoria.
>> Así que ahora, vamos a hacer las cosas un poco más fácil de usar.
Como se recordará, desde Binky última tiempo-- si mi ratón cooperate-- así
tuvimos el código, que francamente, es bastante absurdo.
Este código no logra nada útil, pero era el ejemplo
ese profesor Parlante utilizado para representar
lo que estaba pasando en un programa que involucra la memoria.
>> Así que vamos a volver a contar esta historia muy brevemente.
Estas dos primeras líneas, en Inglés, qué qué, qué le dirías?
Just in razonablemente humano, pero ligeramente términos técnicos, tomar una puñalada.
AUDIENCIA: [inaudible].
>> DAVID J. MALAN: OK, que está estableciendo direcciones para sus variables x e y.
No del todo, porque x e y no son variables en el sentido tradicional.
x e y son direcciones o almacenará la dirección.
Así que vamos a probar esto una vez más.
No es un mal comienzo, sin embargo.
¿Sí?
>> AUDIENCIA: [inaudible].
DAVID J. MALAN: Good.
Creo que eso es un poco más limpio.
La declaración de dos punteros, dos enteros.
Y los estamos llamando x e y.
O si tuviéramos que dibujar esto como una imagen, de nuevo,
recordar simplemente que todos que estamos haciendo con esa primera línea
está dibujando un cuadro como éste, con un valor de basura en ella,
y decir que es X, y luego otro cuadro como éste,
con un valor de basura en ella, llamándola y.
Hemos declarado dos punteros que en última instancia
almacenará la dirección de un int.
Así que eso es todo lo que hay.
>> Así que cuando Binky hizo esto, el arcilla sólo se veía así.
Y Nick sólo tipo de envuelto en las flechas,
como si no están apuntando en cualquier lugar en particular, porque son justo
valores de basura.
No están inicializados explícitamente en cualquier lugar en particular.
>> Ahora, la siguiente línea de código, el recuerdo, era esto.
Así que en razonablemente fácil de usar, pero Inglés bien técnico,
lo que es esta línea de código haciendo?
¿Sí?
>> AUDIENCIA: [inaudible].
>> DAVID J. MALAN: Perfect.
Es la asignación de la parte de la memoria que es del tamaño de un int.
Y eso es la mitad de la respuesta.
Ha respondido la derecha medio de la expresión.
Lo que está ocurriendo en el lado izquierdo del signo igual?
¿Sí?
AUDIENCIA: Y cesionarios a la variable x?
>> DAVID J. MALAN: Y cesionarios a la variable x.
Así que para recapitular, asigna del lado derecho suficiente memoria para almacenar un int.
Pero malloc específicamente devuelve la dirección
de ese trozo de memoria, lo que usted tiene acaba de proponer se almacena en x.
>> Así que lo que Nick hizo la última vez con Binky es arrastró a ese puntero a cabo, la arcilla,
apuntar ahora en un pedazo blanco de la memoria que es igual al tamaño de un int.
Y de hecho, eso significaba para representar cuatro bytes.
>> Ahora, la siguiente línea de código hizo esto, estrella x consigue 42.
Así 42 es sencillo en el lado derecho, sentido de la vida.
Lado izquierdo, estrella x significa qué?
Eso también podría tener gone-- eso está bien.
Okay.
>> AUDIENCIA: Básicamente, ir a la [inaudible]
DAVID J. MALAN: Good.
AUDIENCIA: [inaudible].
DAVID J. MALAN: Exactamente.
Lado izquierdo significa ir a x.
x es la dirección.
Es como 33 Oxford Street, o Ox1.
Y la estrella x significa ir a ese abordar y poner lo que hay?
42.
>> Así que de hecho, eso es exactamente lo que Nick hizo.
Empezó con por, esencialmente, mental
señalando con el dedo a x, siguiendo la flecha
para el cuadro blanco en la mano derecha lado, y poniendo el número 42 allí.
Pero luego las cosas se pusieron un poco peligroso, ¿verdad?
Binky está a punto de perder la cabeza.
>> Estrella y es igual a 13, la mala suerte, significa qué?
Así que medio alguno estrellas van a la dirección en y.
Pero ¿cuál es la dirección en y?
Muy bien, es el valor de basura, ¿verdad?
Lo dibujé como un signo de interrogación.
Nick lo dibujó como una flecha acurrucado.
Y tan pronto como usted trata de hacer estrella y, palabra, ve allí,
pero no hay una legítima dirección, que es una ubicación falsa,
el programa va a estrellar.
Y la cabeza de Binky va a volar aquí, como lo hizo.
>> Así que al final, este programa era sólo falla a toda máquina.
Fue un programa con errores.
Y es necesario que se fije.
Y la única forma, en realidad, para arreglarlo sería, por ejemplo, esta línea,
que ni siquiera pudimos, porque el programa se estrelló antes de tiempo.
Pero si fuéramos a solucionar este problema, lo que efecto hace hacer y x tienen iguales?
Bueno, que apunta esencialmente a en cualquier valor x está apuntando.
>> Así que en la historia de Nick, o la historia de Binky, tanto
x e y señalaban el trozo blanco de la memoria,
de modo que, finalmente, cuando se no es igual a 13 en estrella Y de nuevo,
terminas poniendo 13 en la ubicación adecuada.
Así que todas estas líneas son perfectamente legítimo, a excepción de éste,
cuando sucedió antes realidad y asignado un valor.
>> Ahora por suerte, no lo hace que razonar a través de todos
de este tipo de problemas por su cuenta.
Déjame ir adelante y abrir una ventana de terminal aquí
y abrir, por un momento, un programa súper corto que
También es una especie de sentido.
Es feo.
No lograr nada útil.
Pero sí demuestra cuestiones de la memoria, así que vamos a echar un vistazo.
>> Principal, super simple.
Al parecer llama a una función, f y, a continuación, devuelve 0.
Es un poco difícil de arruinar esto.
Así principal es bastante bueno, hasta ahora.
>> Así que f es problemática.
Y simplemente no poner mucho esfuerzo en nombrarlo
aquí, para mantener la atención en el código.
f tiene dos líneas.
Y vamos a ver lo que está pasando ahora.
Así, por una parte aquí-- y permítanme hacer
esta consistente con el anterior ejemplo-- por una parte,
el lado izquierdo es haciendo lo que, en Inglés?
Es es--
AUDIENCIA: Creación de un puntero.
DAVID J. MALAN: Creación de un puntero a un int y decir que es x.
Así que es la creación de una de esas cajas Sigo dibujando en la pantalla táctil.
Y ahora, en la mano derecha lado, malloc, por supuesto,
es la asignación de una parte de la memoria.
Y para que quede claro, ¿cómo cantidad de memoria que aparentemente
asignación, si sólo tipo de hacer los cálculos aquí?
>> Así que es de 40 bytes.
Y sé que sólo porque sé que un int, en el aparato CS50, por lo menos,
es de cuatro bytes.
Así que 10 veces 4 es 40.
Así que este es el almacenamiento de una x, la dirección del primero de los 40 enteros que
se han asignado espacio atrás, hacia atrás, hacia atrás, hacia atrás.
>> Y eso es lo que es clave sobre malloc.
No se necesita un poco de memoria aquí, un poco aquí, un poco aquí.
Le da un trozo de memoria, contigua, de la operación
sistema.
>> Ahora ¿qué pasa con esto, x soporte 10 es igual a 0?
Línea arbitraria de código.
No lograr nada útil.
Pero es interesante, porque x soporte 10--?
¿Sí?
>> AUDIENCIA: [inaudible]?
>> DAVID J. MALAN: x soporte 10 no tiene que ser nulo.
El detalle nula sólo entra en juego con cuerdas, al final de una cadena.
Pero un buen pensamiento.
>> ¿Qué tan grande es esta matriz, incluso aunque he asignaron 40 bytes?
Es 0 al nueve, ¿no?
Es 10 ints, total.
40 bytes, pero 10 intercepciones, 0 0 indexadas a través.
>> Entonces, ¿qué es que x soporte de 10?
En realidad es un poco basura valor desconocido.
Es la memoria que no pertenece a mí.
No debería estar tocando que número 41, 42, 43, 44 byte.
Me estoy volviendo un poco demasiado lejos.
>> Y de hecho, si me quedo esta programa, que muy bien podría estrellarse.
Pero a veces, tengamos suerte.
Y lo que acaba de demostrar esto-- y, francamente,
nunca se sabe antes de Qué it-- vamos a correr esto.
Es en realidad no bloquee.
>> Pero si cambio de esto, para ejemplo, que sea como 1000,
para hacer esto realmente deliberada, veamos
si podemos conseguir que se bloquee este momento.
Bien, no se estrelló.
¿Qué hay de 100.000?
Vamos a rehacerlo, y ahora volver a ejecutarlo.
Okay.
Ufff.
Bien.
Así que al parecer, una vez más, estos segmentos de memoria, por así decirlo,
son bastante grandes, por lo que podemos tener suerte una y otra vez.
Pero con el tiempo, una vez que llegue ridículo y realmente ir muy lejos en la pantalla,
toca de memoria que realmente, realmente no pertenece a usted.
>> Pero, francamente, estos tipo de bichos van
a ser más difícil y más difícil averiguar por su cuenta.
Pero, por suerte, como programadores, tenemos herramientas que nos permiten hacer esto por nosotros.
Así que esta es, quizá, uno de los programas más feas,
incluso más feo que la salida de gdb.
Pero siempre tiene una línea o dos que son muy útiles.
>> Valgrind es un programa que ayuda a no depurar un programa, per se,
pero encuentra relacionada con la memoria problemas, específicamente.
Se ejecutará automáticamente el código para usted y busca al menos dos cosas.
Uno, ¿hiciste algo accidental como la memoria táctil
eso no te pertenece?
Le ayudará a encontrar esos casos.
>> Y dos, que le ayudará a encontrar algo que se llama
pérdidas de memoria, que tenemos completamente ignorado, ingenuamente,
durante algún tiempo y felizmente.
Pero resulta que, todo esta vez, siempre que sea
usted ha llamado getString en así que muchos de nuestros programas,
usted está pidiendo el operativo sistema para la memoria,
pero tienes ningún recuerdo de vez dándole
espalda, haciendo unalloc, o libre, como se le llama.
No, porque nunca hemos Le ha pedido que lo haga.
>> Pero todo este tiempo, los programas de que has estado escribiendo en C
han sido fugas de memoria, pidiendo a la operación
sistema para obtener más y más memoria para las cadenas y todo eso,
pero nunca lo devolvió.
Y ahora esto es un poco de una simplificación excesiva,
pero si alguna vez te has dirigido tu Mac o tu PC desde hace bastante tiempo, la apertura
un montón de programas, tal vez cerrar los programas,
ya pesar de que su equipo no se ha estrellado,
cada vez es mucho más lento, como si realmente
utilizando una gran cantidad de memoria o recursos, a pesar de que,
si usted no es aún Tocar el teclado,
que podría ser-- pero no podía siempre-- ser que los programas que se están ejecutando
tienen a sí mismos las pérdidas de memoria.
Y siguen pidiendo al OS de más y más memoria, pero olvidándose de ello,
en realidad no lo utilice, pero Por lo tanto, teniendo la memoria de distancia
de otros programas que quieran él.
Así que esa es una explicación común.
Ahora aquí es donde Valgrind de salida es completamente
atroz a los menos y más parecidos cómodo.
Pero lo interesante cosas es justo aquí.
Me está diciendo una escritura no válida de talla cuatro sucede en este programa,
en particular, en la línea 21 de memory.c.
>> Si voy a la línea 21, hm, ahí sí es una escritura no válido de tamaño cuatro.
¿Por qué el tamaño cuatro?
Bueno, esto number-- y podría ser cualquier cosa-- es un int.
Así que es cuatro bytes.
Así que me voy a poner cuatro bytes donde no pertenecen.
Eso es lo que Valgrind es en realidad me dice.
Por otra parte, también lo hará dime, como veremos,
ya que se corre este en un conjunto de procesadores futuros, siempre y cuando has filtraste memoria, lo que de hecho
Que tengo, porque yo he llamado malloc, pero no lo he hecho realidad
llamado, en este caso, libre, que vamos a ver con el tiempo
es lo contrario de malloc.
>> Así que ahora, creo, un último ejemplo.
Así que éste es un poco más arcano, pero es quizás
la razón más grande para tener cuidado con la memoria,
y la razón de que muchos programas y / o servidores web, incluso a este día,
son asumidas por los chicos malos en algún lugar en el Internet que son de alguna manera
el envío de paquetes falsos a su servidor tratando de comprometer sus cuentas,
o tomar sus datos, o simplemente generalmente hacerse cargo de una máquina.
Desbordamiento de búfer, como la nombre indica, medios
desbordante no un int, pero un búfer.
Y un tampón es sólo una forma elegante de decir que es un montón de memoria.
>> Y, de hecho, llamé a una cadena antes de tampón, en lugar de s.
Porque si es una memoria intermedia, como en el sentido de YouTube,
o en cualquier momento que estés viendo un vídeo, que podría haber visto la palabra buffering,
dot, dot, dot.
Es increíblemente molesto.
Y eso sólo significa que su reproductor de video
está tratando de descargar un montón de bytes, un montón de bytes
de un vídeo de internet.
Pero es lento, por lo que está tratando para descargar un montón de ellos
para llenar un tampón, un contenedor, de modo que usted tiene suficientes bytes que puede entonces
le mostrará el video, sin detenerse constantemente.
Pero resulta que, usted puede tener un buffer para este tamaño.
Pero tratar de poner esta cantidad de datos en , y muy malas cosas pueden suceder.
Así, por ejemplo, echemos un vistazo a este desafío para la final de un ejemplo.
Este es otro programa que, a primera vista,
no hace nada super útil.
Tiene una función principal que llama a esa función, f.
Y esa función, f, hasta aquí, tiene una matriz de caracteres, llamado c, de tamaño 12.
Y luego está el uso de este nueva función llamada strncpy.
>> Resulta que, con este sencillo, simple línea de código, a sólo dos líneas,
hemos hecho toda mi programa, y por lo tanto, todo mi equipo,
y mi cuenta de usuario, y mi disco conducir potencialmente vulnerable a cualquiera
que sabe y es lo suficientemente bueno para correr este programa con una línea de comandos cierta
argumento.
En otras palabras, si este chico malo pone dentro de argvargv [1] escribiendo
en el teclado de un muy especialmente diseñado cadena, no abc, 123, pero en esencia,
símbolos binarios que representan ejecutable código, un programa que él o ella escribió,
con este sencillo programa, que es representante de miles de programas de
que son igualmente vulnerables, atrevo a decir, él o ella en última instancia, puede borrar todos
los archivos en mi disco duro, conseguir un parpadeo rápido para que él o ella puede
escribir comandos por su cuenta, correo electrónico todos los archivos a mí mismo.
Todo lo que puedo hacer, o ella puede hacer con este código.
>> No vamos a resolver este bastante todavía.
Y, de hecho, va a implicar una pequeña imagen
así, que pronto vendremos para entender mejor.
Pero por hoy, vamos a terminar en lo que es, con suerte, un poco más
broma XKCD comprensible, hasta que reanudemos la próxima vez.
Bien.
Nos vemos el miércoles.
>> [REPRODUCCIÓN DE MÚSICA]
>> ALTAVOZ: Y ahora, en el fondo pensamientos, por Daven Farnham.
La memoria es como saltar en una pila de hojas de oro en una tarde de domingo.
Soplado viento, lanzando su hair-- oh, echo de menos los días cuando--
>> [Risas]