>> [REPRODUCCIÓN DE MÚSICA]
>> DAVID J. MALAN: Bueno este es CS50 y este es el comienzo de la quinta semana.
Así que hoy, por debajo de los cojines de los asientos, no vas a encontrar nada.
Pero antes, usted debe encontrar estos, un pequeña muestra de nuestro agradecimiento por
todo el trabajo que se pone en el Juego de los Quince.
Simplemente quite el pequeño círculo en el abajo para empezar a jugar para el
resto de la clase.
>> Así que recordar que, o saber que problema planteado cuatro, que salió este fin de semana,
implica escribir otro juego.
Pero esta vez se trata de utilizar un interfaz gráfica de usuario real, no una
interfaz textual como Juego de los Quince era.
Y el juego que está por delante de ti, si todavía no has visto esta próxima,
se ve un poco de algo como esto.
Voy a entrar en mi terminal ventana de aquí en GDB.
Y yo voy a seguir adelante y ejecutar el necesidad de personal, que se puede acceder
después de ejecutar la actualización de 50 como de costumbre.
>> Pero me voy a poner en un poco modo secreto, un pequeño huevo de Pascua,
llamado modo de Dios, por poner a Dios en argv1.
Y tengo que seguir mis propias direcciones, ejecutarlo en mi propia
problema establecido directorio.
Así que ya lo ves una versión completa del juego de Breakout.
De hecho, este es el modo sin manos.
Así que en realidad es -
cautivó a pesar de que podría ser -
bastante trivial para implementar el modo Dios en Breakout, a diferencia del juego de los Quince,
que algunos de ustedes podrían haber abordado para la edición de los piratas cibernéticos.
>> En Breakout es suficiente en Dios el modo con que se haga lo que,
intuitivamente con la pala?
Así que tenga la misma sea cual sea el posición horizontal es de la pelota.
Y mientras lo hace al mismo ritmo con la pelota en movimiento el juego se
Nunca, nunca, nunca te pierdas la pelota y que va a ganar cada vez.
>> Pero en la edición de esta semana de hackers hay algo más que el modo de Dios.
Hay un número de otras características.
Entre ellos, los láseres.
Así que si usted realmente consigue impaciente usted puede iniciar el derribo de los ladrillos
y algunos otros.
Y para aquellos de ustedes que le gustaría calibrar estándar frente a hackers
edición, ya lo veo de esta semana edición pirata informático deliberadamente es una
poco más factible, por ejemplo, que Dios modo estaba con Juego de los Quince.
>> Así que si usted está buscando un estiramiento y usted está buscando un poco de diversión adicional
características no bucean en caso de interés.
Ahora más prácticamente, permítanme señalar a cabo una cosa así.
GDB, que algunos de ustedes no tienen todavía tocado personalmente, lo cual está bien.
Pero ahora es realmente el tiempo para acostumbrarse a esto y cómodo con esta herramienta
ya que hará que sus vidas mucho más fácil, realmente.
>> La conferencia de Per Rob en GDB un par de hace semanas, el recuerdo
que GDB es un depurador.
Es una herramienta que le permite ejecutar su programa, sino ejecutar paso a paso, la línea
por línea, para que pueda hurgar, para que veas las cosas que suceden, por lo
que se puede imprimir valores de las variables.
En pocas palabras, le da mucho más energía que printDef hace.
>> Ahora es cierto, la interfaz es bastante arcano.
Blanco y Negro interfaz textual en su mayor parte.
Los comandos son un poco difíciles recordar al principio.
Pero a pesar de que podría tener que media una hora, una hora, para poner esa adelantado
inversión de tiempo en él, confía en mí.
Ciertamente, para el final del semestre que le ahorrará que un orden de magnitud más
tiempo que eso.
>> Así que a principios de la semana zambullirse
Y en términos de Breakout, sabe que puede hacerlo siempre y cuando usted tiene
el código de distribución o en su propio código en curso en el directorio Pst4.
Sepa que usted puede ejecutar gdb. / Ruptura.
>> Esto va a abrir una ventana como esta.
Déjeme me entrego más de una ventana de terminal.
Y entonces lo que voy a seguir adelante y no, no es sólo ejecutarlo.
Voy a establecer primero un punto de quiebre recuerdo, que permite pausar
ejecución en un lugar determinado.
>> Sólo para mantener las cosas simples que voy a romperse en la línea uno con tan sólo escribir
el número uno.
Déjame volver a abrir esta ventana en realidad porque se está haciendo un
poco pequeño allí.
Así que lo que ahora voy a hacer aquí es si abro mi ventana de terminal.
Vamos, ahí vamos.
>> Así que ahora si vuelvo a selección, Pst4 y ejecutar gdb. / breakout entrar, previo aviso
Voy a romper uno para ajustar un punto de quiebre en la línea uno.
Y ahora me voy a ir por delante y el tipo de ejecución.
Y cuando lo haga, observe nada parece suceder.
>> No hay pop-up.
No hay gráfica interfaz de usuario.
Pero eso es comprensible porque estoy literalmente en la línea uno en mi programa.
Y noto que he avanza rápidamente, específicamente ahora a 62, porque todos
las cosas en la parte superior de este archivo es cosas como los comentarios y las constantes y
cosas poco interesantes por ahora.
>> Así que ahora que estoy dentro del principal, al parecer, en la línea 62.
Y esto es sólo la distribución código, el recuerdo.
Si abro esta por ir, de manera similar, en mi directorio cuadro desplegable en Pst4,
en breakout.c.
Y si me desplazo hacia abajo y abajo y abajo, y déjame ir adelante y enciendo
mis números de línea.
>> Lo que voy a ver, si me desplazo hasta línea 62, es exactamente la línea que
hemos detuvimos en.
Así que esta línea de aquí, 62 años, es donde estamos a punto de serlo.
Así que ahora en GDB, si sigo adelante y tipo ahora A continuación, escriba que va a
ejecutar esa línea.
Y voilá, tenemos la llamado g ventana.
Si no están familiarizados con lo que un GWindow es decir, que no se preocupara.
La especificación le dará a conocer a la misma, como así como una serie de videos de tutorial
incrustado en la especificación.
>> Pero ahora vamos a hacer de este un poco más interesante.
Permítanme pasar esta ventana sobre a un lado un poco.
Permítanme hacer un poco la ventana grande para que pueda ver más.
>> Y ahora déjame ir por delante y hacer la próxima vez.
Y no son mis ladrillos.
Si escribo la próxima vez ahora veo la pelota.
Y si escribo la próxima vez ahora veo la paleta.
>> Y afortunadamente esto no es gedit realmente cooperar mostrándome
todo lo que quiero.
Pero ahora si lo hago al lado de nuevo, siguiente otra vez, estoy
declarar algunas variables.
Y puedo imprimir cualquiera de estos chicos.
Ladrillos de impresión, impresiones de vidas.
>> Y ahora, si sigo haciendo siguiente, noto que voy a ser
dentro de ese bucle.
Pero el código se va a ejecutar exactamente lo que yo esperaba.
Así que cuando llegué a esta función, Esperar por Click, que va a hacer
literalmente eso.
Así que me parecía haber perdido el control sobre el programa.
>> BGF no me da otro aviso.
Pero no se preocupe.
Vaya a mi juego, haga clic en alguna parte.
>> Y listo, ahora se procede a la línea 86.
Así que de nuevo, es muy valiosa, en última instancia, para los problemas de depuración.
Debido a que, literalmente, puede recorrer su código, imprimir cosas fuera y mucho,
mucho, más.
Pero por ahora, las herramientas por sí solas debe te ofrece mucho más.
>> Así que estamos, por supuesto, echar un vistazo en Gráficas ahora, de repente.
Y ahora nuestro mundo se vuelve un poco más interesante.
Y usted sabe, tal vez, de algunos de los videos online que tenemos estos
pantalones cortos que has estado viendo como parte de los boletines de problemas.
>> Y han sido fusilados, deliberadamente, contra un telón de fondo blanco.
Y algunos de ellos tienen la enseñanza Fellows dibujo poco de texto en el
pantalla que se superpone en el lado de ellos.
Pero por supuesto, esto no es lo único que interesante en el mundo real.
Esto es sólo una sala de conferencias con una pantalla grande de color blanco y un telón de fondo.
Y nuestro equipo de producción increíble especie de hace que todo parezca bonito
después de los hechos por los que afloran o superposición de nada
que hacemos o no queremos.
>> Ahora sólo tienes que motivar esta semana y realmente, donde se puede ir, en última instancia,
con la informática.
No sólo después de un problema en cuatro sets.
Pero después de otro curso o un entero currículo es increíble lo que se puede
hacer en estos días, en términos de gráficos en particular.
>> Algunos de ustedes han visto este fluye alrededor en línea.
Pero pensé que te iba a presentar, por tan sólo un par de minutos, un vistazo de lo que
tecnología informática y lo que CGI, gráficos por ordenador se pueden hacer en estos días
con una canción conocida y tal vez la película.
>> [MÚSICA - Lana Del Ray, "JOVEN Y HERMOSA]
>> ALTAVOZ 1: Es sólo un poco increíble, tal vez, lo
omnipresente -
>> [Aplausos]
>> ALTAVOZ 1: Acabo de descargar él.
Pero es realmente increíble, creo que, al igual cómo el software y el código omnipresente y
herramientas como esta realidad.
Así que eso es una muestra de la dirección en el que se puede ir.
Oh, no más Appliance hoy.
Bueno, eso es realmente trágico momento dado el punto Sólo traté de hacer.
>> Muy bien, así que vamos lanzamiento Fusión de nuevo.
Recordar más tarde.
Muy bien, y que debería haber conseguido una enviar por correo electrónico como un aparte si usted recibió un
cuenta así.
Muy bien, así que recuerda que la semana pasada empezamos a pelar este
más tarde conocida como cadena.
>> cadena recuerda un tipo de datos que es declarado en la biblioteca CS50.
Y es parte de las ruedas de entrenamiento que ahora comenzarán a despegar.
Era un concepto útil desde el principio.
Pero ahora se va a poner más interesante y más poderosa para
de hecho ver que debajo de la capilla, una cadena es sólo lo que, se nos dijo?
>> Sí, así que es una llamada char *.
Y el * no denota que hay algún tipo de dirección de los involucrados.
Y así, cuando usted dice char * que acaba de decir una variable cuyo tipo de datos es un
puntero ahora.
El hecho de que no es la estrella que hay simplemente significa que usted está declarando una
llamado puntero.
Y ese puntero va a parecer almacenar la dirección de, por
Por supuesto, un char.
>> Ahora ¿por qué este sentido?
Bueno, lo que es una cadena debajo de la capucha?
Bueno, desde hace algún tiempo que hemos estado diciendo que una cadena debajo de la campana es
sólo h-E-L-L-O, por ejemplo.
>> Pero ya hemos hablado de esto como siendo, en esencia, una matriz.
Y un conjunto entonces mirar un poco de la misma familia, con cada uno de estos
tomar un bocado.
Y luego hemos dicho que hay algo especial volver aquí, el
barra invertida 0 o nulo terminador.
>> Así que todo este tiempo, esta aquí ha sido una cadena.
Pero, en realidad, una cadena es en realidad una dirección.
Y las direcciones, como veremos, son a menudo con el prefijo 0x por convención.
¿Qué 0x denotan?
¿Alguien lo sabe?
>> Así que sólo significa hexadecimal.
Así que se puede recordar, en realidad, desde Pst 1, según creo, una de las de calentamiento
cuestiones de hecho planteadas acerca notación hexadecimal además de
binario y decimal.
Y la motivación aquí es que con hexadecimal que tiene 16
los dígitos a su disposición.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, seguido por a, b, c, d, e, f.
>> Y si se cuentan todos los de arriba, se obtiene un total de 16.
Así que este es en contraste con decimal, donde tenemos 10
dígitos, del 0 al nueve.
Está en contraste con el binario donde sólo tenemos 0 y 1.
>> Pero al final del día usted puede simplemente representar los mismos números, pero
de manera algo diferente.
Y hexadecimal es común porque como resulta que - y vamos a ver esta
más tarde en el curso - incluso cuando lleguemos a la programación de web en el contexto de
HTML y códigos de color, hexadecimal es agradable.
Debido a que cada dígito, resulta, representa cuatro bits perfectamente.
Por lo tanto, sólo un poco de líneas muy bien como veremos con el tiempo vemos.
Así que esto podría ser Ox123 o algo así, la dirección que indica 123
en algún lugar dentro de mi la memoria del ordenador.
>> Pero, por supuesto, surgen algunos problemas Debido a esto subyacente
aplicación.
Y recuerdo que tomé una puñalada en la implementación de una función como esta -
comparar tablero 0 puntos c la semana pasada, que a pesar de que parecía que era
derecho, sino que simplemente no se puede comparar dos cuerdas correctamente.
>> He tirado principal, y me he lanzado lejos los comentarios sólo se centren en el
el código que es de interés aquí.
Y es en rojo porque es buggy.
¿Por qué motivo?
>> Bueno, en la parte superior existe cuando declaré una cadena, lo que realmente estaba pasando
debajo de la capucha?
Bueno, déjame ir a la Aquí la pantalla y dibujar eso.
Así que yo declaré, de nuevo, GetString cadena s.
>> Así que voy a seguir adelante y ahora dibujar s como lo que realmente es.
Va a ser una plaza aquí.
Y yo voy a la reivindicación que eso es 32 bits.
Al menos por lo general es, al menos en el CS50
aparato en una gran cantidad de computadoras.
Voy a llamarlo milagrosamente.
>> Pero ahora recordar que llamado GetString.
Así GetString devoluciones, por supuesto, una cadena.
Si el usuario escribe en h-e-l-l-o entran hola la cadena se devuelve.
Y esa cadena, como acabamos de decir, extremos en algún lugar de la memoria del equipo
con una barra invertida 0 al final.
Voy a llamar esta como la matriz - o bloque contiguo de caracteres -
que en realidad es.
>> Y ahora, ¿qué es getString realmente volver?
¿Qué ha estado volviendo GetString todo este tiempo?
Bueno, nosotros decimos, en semanas anteriores, devuelve una cadena.
Pero más técnicamente, lo que hace GetString volver parecer?
>> AUDIENCIA: Una dirección.
>> ALTAVOZ 1: Una dirección.
Concretamente se devuelve la dirección de el primer bocado, lo que sea.
Sigo usando uno, dos, tres porque es conveniente.
>> Devuelve la dirección de la primera carácter en la cadena.
Y dijimos la semana pasada que que es suficiente.
Porque siempre podemos averiguar dónde el final de la cadena con sólo
iterar sobre ella, tal vez, con una de lazo o un bucle while o algo así
que, sólo en busca de "barra invertida 0", el carácter especial centinela.
>> Y entonces sabemos que la cadena que pasa a ser de longitud -
en este caso -
cinco.
Así que técnicamente lo que hace GetString es devuelve Ox123 en este caso.
Y técnicamente lo que sucede entonces es que almacenamos, en el interior de s, Ox123.
Al final del día, a pesar de que este Es nuevo concepto, los punteros, son
sólo variables.
Pero, por casualidad, almacenar bits que colectivamente representan una dirección.
Así que técnicamente todo lo que obtiene almacenado en s es Ox123.
>> Pero nosotros, como seres humanos -
incluyendo hoy en adelante -
están en realidad no va a importar, por lo general, cuál es la dirección real es
de algún trozo de memoria.
Es sólo a menor nivel de detalle que ser intelectualmente interesante.
Así que me voy a deshacer esto.
Y en cambio, más alto nivel, simplemente decir que cuando estamos hablando de punteros
Voy a llamar más justo arrow fácil de usar que transmite la
misma idea y resúmenes de distancia del pormenores de lo que el real
Dirección subyacente es.
>> Ahora bien, si nos remontamos al código, lo que sucedió la semana pasada si tenemos cadena t
es igual a GetString?
Bueno, si yo de nuevo, escribo en hola esta vez lo voy a conseguir
otro trozo de memoria.
h-E-l-l-o barra invertida 0.
>> Pero porque llamé GetString por segunda vez -
y sé que esto de mirar el código fuente para GetString - incluso
aunque es una coincidencia que hola era escrito en dos ocasiones, GetString no es
va a tratar de optimizar y ser inteligente.
Sólo va a conseguir otro trozo de memoria de la computadora, que es
va a ser en otro domicilio.
Vamos arbitrariamente a decir 456.
>> Y entonces, ¿qué se va a volver?
Se va a devolver 456 y guárdelo en t.
Entonces, ¿qué está pasando en realidad, en el lado izquierdo es que tengo otro pedazo
de memoria, típicamente 32 bits.
Y ahí va a ir Ox456.
Pero, de nuevo, no estoy interesado en estos números particulares más.
Yo sólo voy a abstractamente dibujarla como una flecha.
>> Así que esta es ahora una nueva explicación.
Pero es la misma idea exacta que es estado sucediendo todo este tiempo.
Y así, la razón, entonces, que esta primera versión de comparación era con errores
la semana pasada es la razón?
Cuando lo hagas, si s es igual a los iguales t ¿qué eres realmente
debajo de la capucha comparando?
>> Usted está comparando las direcciones.
Y sólo intuitivamente, claramente, Ox123 no va a ser igual Ox456.
Esos números, esos bits son sólo diferentes.
>> Y así constantemente, la semana pasada, dijo que escribe cosas diferentes, incluso si el
palabras fueron textualmente la misma.
Así que podemos solucionar este problema.
En términos sencillos, ¿cuál fue la solución?
>> AUDIENCIA: Utilice una función.
>> ALTAVOZ 1: Utilice una función.
O las estrellas están definitivamente involucrados, pero el uso de una función para hacer qué?
>> AUDIENCIA: Comparar las cuerdas.
>> ALTAVOZ 1: Comparar las cuerdas.
Así que el problema fundamental era que sólo estaba pensando en la
calidad de las cuerdas que deberá definir comparación de sus direcciones.
Y, obviamente, eso es simplemente tonto ahora, una vez usted entiende lo que está pasando
debajo de la capucha.
Para comparar realmente las cadenas para ver si que son iguales en la forma en que un ser humano
consideraría que dos cadenas son iguales necesitamos compararlas caracteres para
carácter a carácter.
>> Ahora yo podría haber hecho esta muy prolijamente.
Pero familiarmente, estamos utilizando un bucle.
Y justo comparar s abrazadera i contra t i soporte.
s soporte de i + 1 contra t soporte I más 1, y así sucesivamente, en el interior
algún tipo de bucle.
Y si veo a dos personajes que diferentes, o si me doy cuenta de que ooh, s es
más corto que t o más largo que t Lo que puedo decir de inmediato falsa,
no son lo mismo.
>> Pero si me pongo a través de s y t y decir mismo, mismo, mismo, mismo, mismo, final de
ambas cadenas, puedo decir verdad, ellos son iguales.
Bueno, por suerte, hace años alguien escribió ese código por nosotros.
>> Y lo llamaron StrComp para la cadena de comparar.
Y a pesar de que se trata de un pequeño mostrador intuitivo, StrComp devuelve 0 si los
dos cadenas, s y t son los mismos.
Pero devuelve valor negativo si s debe venir antes de t alfabéticamente o
valor positivo si debe venir después de t alfabéticamente.
>> Así que si alguna vez desea ordenar algo, resulta que StrComp es útil.
Debido a que no se limita a decir sí o no, iguales o no.
Le da un sentido de la ordenación como lo haría un diccionario.
Así StrComp, s coma t iguales es igual a 0 significa que el
cadenas son realmente iguales.
Porque quien escribió esta función Hace años, presumiblemente utilizado un bucle
o un bucle while o algo así para integrar en los caracteres de nuevo
y una y otra vez.
>> Pero el problema de dos surgió aquí.
Este fue copy0.c.
Y los dos en rojo es porque está viciado.
Y lo que hicimos aquí?
Bueno, primero que llamé GetString.
Y guardé el valor de retorno en s.
Así que eso es más o menos lo mismo que esta parte superior de la imagen.
>> Pero, ¿qué viene después?
Bueno, déjame ir por delante y deshacerse de un manojo entero de esto.
Vamos a rebobinar en el tiempo para el que sólo tener s, que ahora es consistente con
una línea de arriba.
>> Compruebo.
Si s es igual a es igual a 0.
Ahora, una nota lateral rápida, cuando podría GetString devolver 0?
No hay suficiente memoria.
¿Cierto?
>> Es raro que esto va a suceder, sin duda en un equipo que es
tiene cientos de megas o incluso gigas de RAM.
Pero podría, en teoría, el retorno 0, especialmente si el
usuario no coopera.
Hay maneras de hacer como que no tiene nada de entrada y la trampa
GetString en regresar 0 eficazmente.
>> Así que va a comprobar eso.
Porque si alguno de ustedes han comenzado a get, ya, fallos de segmentación -
que probablemente ha sido una fuente de cierta frustración -
esos son casi siempre el resultado de error relacionado con la memoria.
De alguna manera que en mal estado con respecto a un puntero, incluso si usted no se dio cuenta
hubo un puntero.
Segmentación Así que podría haber inducido fallas ya en la semana uno usando
algo así como un bucle o un tiempo lazo y una matriz por ir demasiado lejos
más allá de los límites de la matriz que algunos usted declaró, en la segunda semana de
particular.
>> Es posible que haya hecho que sea aún en el problema en cuatro sets con Breakout.
A pesar de que probablemente no ha visto ninguna estrella en el código de distribución para
Breakout, resulta que los GRect y GOVAL y otras cosas,
esos son en realidad punteros debajo de la capucha.
>> Pero Stanford, como nosotros, una especie de pieles que detalle al menos para las bibliotecas
fines, al igual que lo hacemos de cuerda y char *.
Pero GRect y GOVAL y todos aquellos cosas que ustedes están o van a utilizar
esta semana son en última instancia, direcciones de memoria.
Sólo que no lo sepa.
>> Así que no es sorprendente, entonces, tal vez, que usted puede tropezar con alguna
fallos de segmentación.
Pero lo que es interesante aquí ahora, si después comprobamos por 0 hacemos
cadena t consigue s.
Bueno, déjame declaro t.
Voy a dibujarlo como un cuadrado, 32 bits, lo llaman t.
Y luego me voy a hacer se pone s.
>> Bueno, ¿qué significa eso?
Bueno, es un poco difícil pensar al respecto del cuadro sabio.
Pero vamos a pensar en lo que hay dentro de x?
Lo que es, literalmente, dentro de esta variable?
El valor Ox123.
>> Así que cuando digo cadena t consigue s, que sólo literalmente significa tomar el número
en s, que es Ox123 y ponerlo Ox123.
O pictóricamente, si que tipo de resumen lejos de ese detalle que tiene la
efecto de hacer literalmente esto también.
>> Así que ahora, pensar en volver a la semana pasada cuando se procedió a la capitalista T. I
lo hizo T bracket 0.
Bueno, T bracket 0, a pesar de que se trata de un puntero, se puede tratar como si
es una matriz, con un cuadrado notación de corchetes.
>> Entonces, ¿dónde está el soporte T 0?
Bueno, es la hora.
Y así, cuando utilizamos esta línea de código, dos superior, que es en que c type.h
archivo de cabecera, que es donde es declarada.
Usted está capitalizando esta H. Pero, Por supuesto, esa es la misma h exacta que es
interior de s, por así decirlo.
Y por lo que ahora usted ha cambiado o capitalizado tanto el original como la
así llamada copia.
Debido a que usted no hizo una copia en el forma en que un ser humano querría que fuera.
>> Entonces, ¿cuál era el punto de referencia aquí, en copy1.c la semana pasada?
Funciones, así que en realidad podría copiar la cadena.
Y fundamentalmente, ¿qué necesitamos para hacer con el fin de copiar la cadena?
>> Bueno, en esta versión verde aquí estoy vamos a hacer un nivel bastante bajo.
En realidad, hay funciones podrían ayudar con esto.
Pero la más básica y la más uno familiarizado, al menos, pronto será
familiar para nosotros, es el siguiente -
por lo que uno en la primera línea de código en verde ahora.
>> Yo sólo reescribió s como char *.
No hay funcional diferencia allí.
Me acaba de lanzar lejos la biblioteca y CS50 Voy a llamar a ser lo que es, un char *.
>> Ahora punto, punto, punto, porque había comprobación de errores que no es
interesante hablar de nuevo.
Así que ahora t es declarada.
También él es un char *.
Así que dibujé una pequeña plaza en la pantalla como antes.
>> Pero en el lado de la derecha, malloc, hemos dicho es la memoria asignar.
Así que asignar parte trozo de memoria.
¿Y cuántos bytes es lo que realmente desee asignar, ¿le parece?
>> Pues bien, la longitud de la cadena de s.
Así que si es hola eso es va a ser cinco.
Diremos h-e-l-l-o.
Así que cinco bytes.
>> Pero entonces, más 1, ¿por 1?
El carácter 0.
Si no dejamos espacio para este tipo que podría crear una situación accidental
donde la cadena es h-e-l-l-o.
Y entonces el siguiente GetString tiempo es Llamé y me introduzco en, por ejemplo,
David, D-a-v-i-d, la computadora va pensar que s es en realidad
h-E-l-l-o-D-A-V-i-d porque hay sin romper entre esas palabras.
>> Así que tenemos que romper.
Así que no queremos cinco.
Queremos seis bytes.
>> Y me dicen bytes.
Pero en realidad es el tamaño época del carbón.
Técnicamente carbón es casi siempre un solo byte.
>> Pero para hacer que nuestro código portable, por así decirlo, para que funcione en
diferentes sistemas aunque podría ser algo diferente debajo de la
campana, voy a genéricamente decir el tamaño de caracteres de manera que
mi código siempre funciona.
Y yo no tengo que volver a compilar sólo porque yo actualizo mi computadora o uso
alguna plataforma diferente.
>> Así que tengo 6 veces el tamaño de un char, que pasa a ser 1.
Así que eso significa malloc podrían dame seis bytes.
¿Qué es eso en realidad haciendo?
Bueno, déjame Hacer Retroceder en el tiempo aquí a dónde estamos en la historia.
>> Así que si vuelvo aquí, he declarado char * llamada t.
Yo ahora he llamado malloc durante seis bytes.
Y ahora me voy a sacar los seis bytes al igual que la gama anterior.
Pero yo realmente no sé lo que es dentro de esta matriz.
>> Si se asigna memoria resulta que no se puede confiar en que hay un poco de
valor conocido allí.
Podría haber sido utilizado por algo otra cosa, alguna otra función, alguna otra
línea de código que usted escribió.
Así que en general, llamaremos a estos residuos valores y dibujarlos, tal vez, como
signos de interrogación, sólo indican que no saben lo que está realmente allí.
Y eso no es gran cosa, siempre y cuando nos son lo suficientemente inteligentes como para sobrescribir los
valores de basura con números o caracteres que nos importan.
>> Así que en este caso, ¿qué voy a hacer?
Bueno, mi línea de código siguiente, tengo cuatro.
int i obtener 0, n obtiene el longitud de la cadena de s.
Así que un familiar para bucle.
I es menor o igual a n, que por lo general está por encima.
>> Pero esta vez es deliberada.
I + +, y entonces yo simplemente hago t i soporte Obtiene s.
Debido a que mi imagen se ve como esto en este momento, almacenada en t es el
dirección de ese fragmento al azar de la memoria cuyos valores son desconocidos.
Pero tan pronto como yo t soporte 0 que me pone aquí.
>> Y lo que termina siendo atraído allí?
Terminamos poniendo h.
Porque eso es lo que está en el soporte s 0.
Y luego lo mismo para E y L, y L, y o.
>> n, ¿por qué me voy arriba a través de un igual al n?
Debido al carácter 0.
Así que para ser claros, entonces, si realmente borrar cualesquiera que éstas basura
valores y luego en realidad se basan en lo que espero, esto es s soporte 1, 2,
3, 4, además de eso se arrastra nuevo personaje.
>> Y ahora si continuamos más allá del punto, punto, punto en esta versión correcta
y capitalizado t bracket 0 Lo haría, de Por supuesto, se capitaliza sólo esta
tipo aquí, que conceptualmente, era en última instancia la meta.
Así que eso es todo el puntero se encuentra.
>> Y usted ha estado usando durante semanas ahora en el contexto de cadenas.
Pero debajo de la capucha son un poco más complejo.
Pero si usted piensa acerca de ellos en este forma pictórica Propongo que son
probablemente no todo lo que da miedo, ya que podría parecer a primera vista, a primera vista,
particularmente con tal nueva sintaxis.
¿Tiene preguntas sobre los punteros, cadenas o caracteres?
¿Sí?
>> AUDIENCIA: ¿Puede volver a la [inaudible]?
>> ALTAVOZ 1: Por supuesto.
>> AUDIENCIA: Así que ¿cómo es que en su último línea, usted no tiene una línea de t *
y una * s en la línea?
¿No tienes la referencia a la -
>> ALTAVOZ 1: Ah, una muy buena pregunta.
¿Por qué no tengo un t * ya * s?
Debido brevemente, la semana pasada, al igual que en nuestro función de cambiar, he dicho que cuando
tienes un puntero el medio por el que vas allí como lo hicimos
físicamente en el escenario, era en realidad utilizar el operador estrella.
>> Resulta que esta de corchetes notación es lo que llamaremos sintáctica
azúcar, que es sólo una forma atractiva de diciendo que es la notación abreviada de
exactamente lo que estás describiendo.
Pero es un poco más intuitivo.
Y a riesgo de hacer este parecer más complicado de lo que tiene que ser,
lo que realmente está pasando aquí es la siguiente -
Si digo * t que eso significa ir a la dirección almacenada en t.
>> Así que, literalmente, si t es el almacenamiento de la dirección de ese h
inicialmente, * t significa ir aquí.
Ahora, ¿qué significa t bracket 0?
Exactamente lo mismo.
Es sólo un poco más de usuarios amigable para escribir.
>> Pero no he terminado todavía.
No puedo decir * t * s consigue.
Porque lo que estaría haciendo entonces?
Estaría poniendo h, h, h, h, h a lo largo de todo el asunto.
¿Cierto?
>> Debido a * t es ir a la dirección en t.
Pero estamos dentro de un bucle.
¿Y qué valor estoy incrementando, por supuesto, en cada iteración?
i.
>> Pero hay una oportunidad aquí, ¿verdad?
A pesar de que esto se siente como se está haciendo un poco más sofisticado
que la notación de corchetes que hemos utilizado durante algún tiempo -
déjame deshacer mi h cambio allí -
a pesar de que esta es ahora conseguir un poco más elegante, la idea básica, si * t
significa aquí y * t es sólo ir a la dirección en t.
>> Pero ¿cuál era la dirección en t?
El número seguimos usando?
Como Ox456, vamos a traer esa vuelta sólo por el bien de la discusión.
Bueno, si quiero llegar a la dirección en t cadena, sólo quiero ir,
esencialmente, 456.
>> O más bien, 457.
Sólo tengo que añadir uno.
Pero no puedo hacer eso, ¿verdad?
Porque t, a pesar de que sigo dibujando ahora como una flecha, que es sólo una
número, Ox456.
Y si añado uno a eso, o más en general, si añado yo para que yo pueda
realmente conseguir exactamente donde quiero.
Así que si yo realmente hago esto -
y esto es lo que se llama ahora Aritmética de punteros -
Me puede quitar esta línea.
Lo cual es, francamente, creo que más claro y un poco más fácil de usar para leer.
Pero esto no es menos correcto.
>> Esta línea de código ahora está utilizando aritmética de punteros.
Es como decir ir a la siguiente dirección -
cualquiera que sea el inicio de t es, que es t plus i, que inicialmente
es 0, lo cual es genial.
Porque eso significa el comienzo de t más 1, más 2, más 3, y así sucesivamente.
Y el mismo acuerdo con s.
>> Así azúcar sintáctica para esto.
Pero la comprensión de lo que realmente está pasando debajo de la capucha, yo diría,
es en realidad útil en y de sí mismo.
Porque significa ahora que no hay mucho más la magia sucede
debajo de la capucha.
No va a haber muchos más capas que podemos pelar de nuevo para usted.
Esta es c.
Y esta es la programación.
Muy buena pregunta.
>> Muy bien, así que esto fue que con errores programa que me refería antes.
permuta era defectuoso.
Si parecen funcionar.
Recordemos que al igual que con la leche y el jugo de naranja - que empecé
beber la manifestación de hoy.
Así que al igual que con el jugo de naranja y la leche, que tenía que usar un
variable temporal, tmp, para celebrar una temporalmente para que pudiéramos entonces
cambiar su valor y luego actualizar b.
>> Pero esta función, decíamos, o esta programa en el que esta función era
escrito que estaba mal y defectuoso, por qué?
¿Sí?
>> AUDIENCIA: [inaudible].
>> ALTAVOZ 1: Exactamente, cuando usted llama swap -
o más en general, cuando se llamar a casi cualquier función -
si los argumentos de esa función son primitivos, por así decirlo, enteros y caracteres
y dobles y carrozas, cosas sin estrellas, está de paso en una copia de
el argumento.
Así que si x era 1 e y era 2, una va que es 1 y b va a ser 2.
Pero ellos van a ser diferentes trozos de bits, diferentes trozos de
memoria que resultan ser el almacenamiento de valores idénticos.
>> Así que este código es super perfecta en el intercambio de a y b.
No es bueno en el intercambio -
en el ejemplo de la semana pasada -
x e y.
Porque de nuevo, son en el ámbito equivocado.
>> Ahora, ¿cómo vamos a arreglar esto?
Tuvimos que hacer la función mirar un poco más feo.
Pero una vez más, tenga en cuenta lo esto sólo significa.
>> Y, de hecho, me dejó, por coherencia, cambiar una cosa por lo que es idéntico al
lo que acabamos de hacer.
Como mencioné la semana pasada, no lo hace importa a dónde va.
De hecho, por lo general usted pondría la protagonizará junto al nombre de la variable.
Pero creo que sería un poco más fácil a considerar el * al lado de la
tipo de datos en el sentido de que es un puntero a un int en este caso.
>> Entonces, ¿qué estoy haciendo aquí?
Yo estoy diciendo que no me dan un int seguido de otro tipo int
llamándolos a y b.
Dame la dirección de un int.
Dame la dirección de otro int.
Llame a los direcciones a y b.
>> Y a continuación, utilizando la notación abajo * a continuación, ir a cada una de esas direcciones
según sea necesario para obtener ya sea o establecer su valor.
Pero hay una excepción aquí.
¿Por qué no tengo un * junto al tmp?
¿Por qué no hago esto, por ejemplo?
Se siente como si yo debería ir a por todas y corregir todo.
¿Sí?
>> AUDIENCIA: [inaudible].
>> ALTAVOZ 1: No he declarado tmp como una cadena.
Así que esto iba a declarar, en este caso, una tmp es la dirección de un int.
Pero eso no es todo lo que quiero, por un par de razones.
>> AUDIENCIA: Usted no quiere para intercambiarlas.
>> ALTAVOZ 1: Exactamente, yo no quiero cambiar nada con tmp. tmp es sólo
semana y un cosas.
Todo lo que quiero es una variable para almacenar un número.
Ni siquiera me preocupo por las direcciones en este momento.
>> Sólo necesito 32 bits o por lo que para almacenar un int.
Y quiero poner en esos 32 bits todo lo que no está en una, por así decirlo, pero
lo que está en una, para ser más precisos.
Porque si a es una dirección, * un medio ir allí y obtener el valor 1.
Por ejemplo, en el ejemplo de la semana pasada o en el caso de b, obtener el valor de 2.
>> Entonces, ¿qué está pasando realmente?
Permítanme llamar una foto aquí donde se sólo desmenuzar parte de hoy.
Pero esto va a seguir apareciendo desde hace bastante tiempo.
>> Esto, afirmo, es lo que el equipo de la memoria se ve como cuando se ejecuta una
programa, cualquier programa.
Cuando se ejecuta un programa en la parte superior de memoria RAM de su computadora - así que pensar en
este rectángulo, en verdad, ya que su RAM del ordenador o la memoria, todo 101
mil millones de bytes de la misma, todos de dos mil millones bytes, todos dos gigabytes de la misma,
cualquiera que sea la cantidad que se tiene es, dibujemos como un rectángulo.
Y afirmo que cuando se ejecuta un programa de como Microsoft Word o Chrome
ni nada de eso, los bits que Microsoft o Google que escribieron -
en los casos de los programas -
se cargan en la memoria del equipo donde pueden ser ejecutadas más
rápidamente y se introduce en la CPU, lo cual es el cerebro de la computadora.
>> Y en TAM están almacenados en el mismo la parte superior de su programa, por así decirlo.
En otras palabras, si se trata de un trozo de memoria, cuando se hace doble clic en
Microsoft Word, los bits vienen fuera del disco duro.
Ellos se cargan en la memoria RAM.
Y nos empujamos hacia arriba en la parte superior de este rectángulo conceptualmente.
>> Bueno, el resto de su memoria es utilizado para diferentes cosas.
En la parte superior se ve inicializar los datos y los datos Uninitialize.
Esto tiene que ver, en su mayor parte, con constantes o variables globales
que tienen valores.
Pero más sobre esto en otro momento.
>> Entonces usted tiene el montón, que vamos a volver a.
Pero en el fondo es la parte que es particularmente pertinente en estos momentos.
Es la llamada pila.
Así que al igual que en la mayoría de cualquier sala D aquí en campus, usted tiene esas bandejas que
acaba de apilar en la parte superior de cada otra en la que usted puede poner la comida y otras cosas.
La pila en un sistema informático es muy similar.
Excepto mientras que la bandeja, ya que utilizamos en el comedor, por supuesto, se entiende
para llevar las cosas de las bandejas o los marcos -
como vamos a llamar a ellos - en un ordenador memoria se utiliza para mantener
variables y valores.
>> Así que lo que realmente sucede debajo de la capucha?
Bueno, déjenme se voltea a la pantalla aquí.
Y vamos a centrarnos sólo en la parte inferior por un momento.
Si esta es la parte inferior de mi la memoria de la computadora resulta cuando
llame a la función principal - lo que ocurre, francamente,
automáticamente para mí -
Me sale un trozo de memoria en el fondo de mi memoria RAM por así decirlo.
Y aquí es donde los principales de variables locales van.
Es el lugar donde argc y argv quizá ir, y cualquier variable que
declarar dentro del principal.
Terminan en la parte inferior de la memoria RAM del ordenador.
>> Ahora supongamos que la principal llama a una función tales como el canje, al igual que lo hizo la semana pasada?
Bueno, esencialmente ponemos una nueva bandeja, un nuevo marco, en mi trozo de memoria.
Y yo voy a describir esto como pertenencia a la función de intercambio.
>> Ahora lo que hay dentro de canje?
Bueno, basado en el programa de la semana pasada y el que acabamos de ver un extracto del,
dentro del marco del intercambio, o el intercambio de bandeja, son lo que las variables?
Bueno, a y b.
Debido a que esas eran sus argumentos locales, más una tercera, tmp.
Así que en realidad, yo podría llegar a esta un poco más limpiamente.
Déjame ir adelante y deshacer la etiqueta.
Y permítanme pretendo que usted sabe lo que?
>> una probablemente va a terminar aquí.
B va a terminar aquí.
Y tmp va a terminar aquí.
Ahora, el orden podría ser un poco diferente.
Pero conceptualmente esta es la idea.
>> Y justo en conjunto, esto es lo que llamaremos marco de intercambio, o
bandeja de comedor-sala.
Y el mismo trato con principal.
Pero no voy a volver a dibujar eso.
Pero ahí es donde argc y argv y cualquier de sus variables locales como X e Y
podría ser así.
>> Así que ahora considerar lo que realmente está sucediendo cuando se llama intercambio.
Cuando se llama a swap, la ejecución de código como esto, usted está pasando, en el
versión con errores, a y b como copias de x e y.
Así que si lo hago ahora extraigo esta en la pantalla -
tiene que mejorar en esto -
por lo que la historia que estaba contando a mí mismo se encontraba en esta versión con errores, cuando nos
llamar permuta pasando literalmente a y b como enteros, ¿qué está pasando realmente?
>> Bueno, lo que realmente está sucediendo es esto.
Déjame ir adelante y deshacer simplemente para aclarar algo de espacio aquí.
Así que esta es la memoria de mi ordenador.
>> Así que si tengo, por ejemplo -
En realidad vamos a hacerlo de esta manera -
si afirmo que esto es x, el almacenamiento el valor 1 al igual que la semana pasada.
Y esto es a, almacenar el valor 2 al igual que la semana pasada.
Y esta es la principal, cuando llamo swap, por lo tanto a mí mismo que da acceso a una y
b y tmp, que voy a afirmar que esta es una y esta es 1.
>> Esta es la b.
Esto es 2.
Esto se llama tmp.
>> E inicialmente, tiene algún valor basura hasta que lo almaceno en una,
que es 1.
Entonces yo voy a continuación y el cambio un ser qué?
El valor de B.
>> Y así que ahora tengo dos aquí.
Y entonces dijimos b consigue tmp.
Una vez más, al igual que una comprobación de validez, la tercera línea de código que aquí es simplemente esto
uno, b consigue tmp.
>> Y así, por último, ¿qué hago?
Sigo adelante y B cambian para ser lo el valor de tmp es, que es 1.
Yo no toco de nuevo tmp.
>> Pero ahora, el problema es tan pronto como swap devuelve, porque no es la entrega
volver algún valor, no hay retorno declaración explícita en ella.
¿Qué está sucediendo realmente?
Bueno, básicamente todo esto de memoria -
Aceptar, por lo visto el borrador le gusta sólo un dedo a la vez -
simplemente desaparece.
>> Ahora bien, en realidad no lo es ir a ninguna parte.
Pero usted puede pensar en él ahora como signos de interrogación.
Debido a que ya no es realmente en uso.
Y no se hace nada con esos valores.
>> Así en el caso de la versión verde de este código, lo que en su lugar está siendo
pasado a la permuta?
Así direcciones.
Así que la dirección de xy la dirección de y.
Así que si volvemos a contar esta historia una última tiempo, y yo en realidad dibujo de intercambio de nuevo,
pero con punteros, siendo esta una, esta siendo b, y siendo tmp, lo que es
efectivamente almacenada en una en este verde versión de mi código en la que estoy pasando
en las direcciones?
>> Va a ser un puntero a x.
Así que podría dibujar una flecha.
Pero vamos a usar la misma arbitraria ejemplo como antes.
Digamos que se trata de algo así como Ox123.
Y esto va a ser porque Ox127 es cuatro bytes de distancia porque es un
int, por lo Ox127.
>> Y otra vez, estoy tomando algunas libertades con los números.
Son mucho más pequeños de lo que sería ser en realidad y en un orden diferente.
Pero así es como la imagen ahora es diferente.
>> Pero cuando se utiliza este código verde y yo int tmp consigo * a.
* Un medio para hacer lo siguiente, tome la electrónico que sea en un e ir a la misma,
que es 1.
Y eso es lo que luego puse en tmp.
Mientras tanto, en la siguiente línea de código aquí, * a se b, ¿qué significa eso?
>> Bueno, * a, así que ve aquí obtiene * b, lo que significa ir allí.
Y eso significa poner el valor a allí.
Finalmente, la última línea de código simplemente dijo * b consigue tmp.
>> Así b dice ir allí y sobrescribir con tmp, que, en este caso, va
ser, de nuevo, 1.
Y esta es la razón por la versión verde de nuestro código funciona, mientras que el rojo
versión nunca lo hizo.
Todo simplemente se reduce a cómo el la memoria se gestiona y donde es
efectivamente despachado a su la memoria RAM del ordenador.
Y por ahora, eso es una de las cosas de que la pila se está utilizando para.
>> Preguntas sobre el diseño?
En los punteros?
O el intercambio?
>> Muy bien, así que malloc, recordar, hizo algo como esto.
Este fue un ejemplo muy simple.
Y este fue el que Binky nos presentó a, aunque bastante
rápidamente, al final de la clase.
Maldita sea, aquí vamos de nuevo.
>> Así que recuerda que este fue el ejemplo que Binky nos presentó, aunque
algo rápidamente al final de la clase.
Y aquí hemos utilizado malloc realmente para el segundo tiempo.
Debido a que la primera vez que lo usamos para crear suficiente RAM, asignar suficiente memoria RAM
para almacenar una cadena.
>> Esta vez Binky mantuvo simple.
Así que es sólo para almacenar un int, al parecer.
Y eso es totalmente bien.
Es un poco raro, francamente, a utilizar malloc para asignar un int.
Pero el punto de animación con plastilina de Nick era realmente sólo contar la historia de lo que
sucede o no sucede cuando maltratas memoria.
>> Así que en este caso, este programa hizo un par de cosas.
En el primer caso, aquí, declara un puntero llamado x para un int.
A continuación, se declara un puntero llamada y de un int.
A continuación, almacena en x, ¿qué?
Otra persona ahora.
Lo que se almacena en x de acuerdo con la tercera línea de este programa?
>> AUDIENCIA: [inaudible].
>> ALTAVOZ 1: Bueno, no del todo bytes, por ejemplo.
Sea más preciso ahora.
Lo que se almacena en x?
Una dirección, creo que lo escuché.
>> Entonces, ¿qué volver malloc?
malloc asigna conductualmente un trozo de memoria.
Pero ¿cómo se dará acceso a ella?
Devuelve qué?
La dirección del primer byte en el bloque de memoria.
>> Ahora, esto es muy simple.
Es sólo un byte, es decir, la dirección que estamos recibiendo de vuelta es la
dirección de todo el asunto.
Así almacenado en x entonces, es la dirección de ese trozo de memoria.
Mientras tanto, ¿qué pasa después?
Así que en realidad, vamos a seguir adelante y alargar esto muy rápido.
>> Así que si vamos a la pantalla aquí y jugamos esto int * x e int * y
que va a hacer lo que para mí?
Yo sostengo que sólo va a hacer algo como esto y llamarlo x, y
esto y lo llaman y.
Mientras tanto, la tercera línea de código es va a asignar el tamaño de un int,
que pasa a ser - lo siento si dije uno antes me refería a uno int -
cuatro bytes en un ordenador típico.
Por lo menos con el aparato CS50.
>> Así que esto va a asignar , ¿quién sabe?
En algún lugar por aquí.
Y esto se almacena en algún abordar buey, ¿quién sabe?
Pero, ¿qué va a quedar vuelto es esa dirección.
Pero vamos a dibujar este pictóricamente tan sólo una flecha así.
>> Ahora, en la siguiente línea * x obtiene 42.
¿Qué * x significa en términos simples?
Sólo tienes que ir allí.
Ir a esa dirección.
O en otras palabras, seguir la flecha y poner 42 allí.
Pero entonces algo malo ha pasado a Binky, ¿verdad?
>> Recordemos que la línea cinco aquí, * y consigue 13, de hecho, un número de mala suerte,
hizo lo que para nosotros?
Bueno, * y significa ir allí.
Bueno, esto no se ha dado un valor todavía, ¿verdad?
El código no tiene siendo y inicializado a nada.
Habíamos x está inicializado a una dirección.
Pero y fue declarado arriba.
Pero entonces, un punto y coma, sin valor fue en realidad poner en él.
Así que es justo decir que esta un valor basura.
¿Quién sabe lo que hay allí?
Son los restos de los bits que se utilizaron por alguna línea de código anterior en
mi programa.
>> Así que si me dicen que vaya allí, esto es como, No tengo ni idea de donde esta flecha es
va a terminar.
Y ahí es cuando normalmente conseguir un fallo de segmentación.
Si accidentalmente eliminar la referencia, por lo que hablar, o ir a una dirección que no es
en realidad una dirección legítima, suceden cosas malas.
>> Y eso es exactamente lo que sucedió pensar Binky.
Así que recordar que la historia que Nick estaba diciendo aquí fue la misma idea que lo
He dibujado con la ilusión de tiza en el tablero allí.
X e Y se declaran.
>> Entonces asignamos el tamaño de un int y almacenado en x.
A continuación, la siguiente línea nos hizo * x.
Esta fue la varita mágica de Nick de eliminación de referencias.
Eso puso 42 en la memoria señalado por x.
>> Pero aquí es donde las cosas salió horriblemente mal.
¿Cierto?
Hemos tratado de eliminar la referencia y.
Pero y tenía algún valor falso, ¿no?
>> Esa flecha en la parte inferior izquierda esquina, no es
en realidad apunta a nada.
Es una especie de hacer lo que no aquí en el tablero.
Así que las cosas malas le suceden, la segmentación criticar o culpa Binky, en este caso.
>> Pero si nos fijamos entonces que al hacer x consigue y ¿Cómo cambia la historia?
Bueno, si lo hago x consigue y, eso es efectivamente lo mismo que decir
sea ​​lo que sea, Ox-algo va a ser lo mismo aquí,
Ox-algo.
O pictóricamente dibujaremos una flecha.
>> Así que aquí en el tablero con Binky, con la siguiente línea de
código, * y significa ir allí.
¿Dónde hay?
Significa por aquí.
>> Y cuando nos ponemos al día que para ser 13 sólo implica ir y
escritura 13 aquí ahora.
Así que tal vez no completamente sencillo a primera vista.
Pero para resumir y utilizar la misma jerga Binky que se utiliza aquí, así
los dos primeros asignan los punteros, X e Y, pero no los pointees.
Y no es un pointees término que se utiliza generalmente.
Pero puntero absoluto es.
Pero es lo que se señaló en en la nomenclatura de Binky.
>> Esta línea siguiente, por supuesto, asigna un int pointee.
Así que un trozo de memoria - como dibujé sobre el el lado derecho allí - y establecer
x igual a apuntar a la misma.
Esto elimina referencia x para almacenar 42 en la memoria que se está apuntando a.
Y a continuación, esto, por supuesto, era una cosa mala.
Porque y no apuntaba en nada.
Esto lo arregla.
Así que esto es todavía programa defectuoso.
El hecho de que estamos soplando a través de la código línea por línea y decir, bueno,
deja que choque allí.
Eso es una mala cosa.
Las probabilidades son el programa sólo va a abortar por completo en esa línea.
Pero si usted fuera a quitar el estrellado línea y sustituirla por los dos últimos
líneas allí se asignan -
mediante la asignación de puntero - y para que apunte a x como punto t.
Y luego deja de hacer referencia Y de una manera muy segura.
>> Entonces, ¿dónde nos deja esto?
Bueno, resulta que debajo de la capucha en la biblioteca CS50, los punteros son
utilizado a lo largo.
Y que realmente comenzaremos a pelar copias de esa capa en poco tiempo.
Pero resulta también, una expresión que algunos de ustedes podrían estar familiarizados con,
en particular los más cómodo, es en realidad el de una muy popular
sitio web, o de desbordamiento de pila, estos días.
>> Pero esto en realidad tiene muy significado técnico.
Ahora sabemos lo que una pila sea.
Es como una pila de bandejas el interior de un comedor.
>> O en el interior de su equipo de memoria sus dichos fotogramas
que son utilizados por funciones.
Bueno, resulta que, debido a que muy simple implementación de
la memoria y los marcos en la llamada pila, usted puede tomar el control
de un sistema informático con bastante facilidad.
Usted puede cortar en un sistema si la gente como nosotros no hemos escrito nuestro código
particularmente bien.
>> Si la gente como nosotros utilizan trozos Memoria o el uso de matrices -
incluso más comúnmente -
pero a veces se olvide de comprobar la límites de nuestra gama como puede ser que
tiene usted mismo a veces, y repetida demasiado lejos más allá del final de una matriz.
En el mejor de los casos, el programa de sólo podría bloquearse.
Fallo de segmentación, tipo vergonzoso.
No es genial, pero no es necesariamente una enorme mala cosa.
>> Pero si el programa es en realidad el verdadero equipos de los usuarios, si se está ejecutando
en un sitio web que la gente al azar reales en el Internet están golpeando, dejando
personas inducen cosas malas en su código es en general, no es una buena cosa porque
que significa una oportunidad para tomar el control del equipo.
Y esto se va a ver un poco críptico.
Pero pensé que te gustaría asusto con este último ejemplo aquí.
>> He aquí un ejemplo de código.
Y hay una buena Wikipedia artículo que camina a través de
esto con más detalle.
Tengo principal en la parte inferior de llamada foo, pasando argv de 1.
Y eso es sólo para que pueda ejecutar el programa y pasar
una entrada arbitraria.
>> Y entonces foo es declarado encima de la tapa como la aceptación de una cadena, o más
precisamente, un char *.
A continuación, declara una matriz de caracteres.
Llame a un tampón, más en general, de tamaño 12.
Así que 12 caracteres pueden caber dentro de esa matriz llamada c.
>> Y a continuación, utiliza esta nueva función, que es nuevo, pero no es difícil de
entender, copia de la memoria.
Se copia la memoria del bar, que era el pasado n variables, sea cual sea el
usuario escribió en argv 1 en c.
¿Cuántos bytes?
La longitud de la cadena de la barra.
>> Así, en otras palabras, si el usuario escribe en h-e-l-l-o entrar, la longitud de la cadena
hola es de cinco.
Así que cinco de esos bytes se va a poner copia en la matriz llamada c, que
es de tamaño 12.
Pero lo que el usuario escribe en un mucho más tiempo palabra que es 13 caracteres o 14
caracteres o 100 caracteres o más?
>> ¿A dónde van a ir?
Bueno, ese marco, dicha bandeja en la pila de comedor-sala,
que van a ir allí.
Y sólo va a empezar a sobrescribir otras cosas que ya está
en la pila, desbordando la pila, por así decirlo.
>> Así pictóricamente, creo que de esta manera.
Esto es sólo una versión colorida de la imagen que hemos venido señalando.
En la parte inferior, digamos, es principal.
Y en la parte superior, lo que estamos viendo ahora es el marco, color codificados ahora, para un
función llamada foo.
Pero lo que es interesante aquí sobre foo es que aquí es su marco.
Así se dibuja al igual que yo lo hizo, pero en color azul claro.
Y ahora, este es el lugar donde c abrazadera 0 va.
Y aquí es donde el soporte c 11 va a terminar.
>> En otras palabras, se pasa a ser representado como un cuadrado.
Pero si te quedas plopping bytes abajo - o caracteres - que van a terminar
hasta en la ubicación 0 hasta el final hasta a 11 porque es 0 indexada.
>> Pero ¿dónde está el carácter 13 va a terminar?
¿Dónde está el 14?
¿Dónde está el carácter número 50 va a terminar?
>> Se va a seguir bajando.
Porque a pesar de que hemos llamado la Imagen con la pila de crecer, la
direcciones, resulta que van desde direcciones pequeñas, pequeñas
punteros, a las direcciones de los grandes.
Por lo tanto, sólo sigue subiendo y subiendo.
>> Así que si el usuario teclea hola, eso es genial.
No bug, no hay problema, todo el mundo está a salvo.
Pero si el usuario escribe en lo que vamos a llamar a código acusatorio, representada
genéricamente como, ataque, ataque, ataque, ataque, ¿qué puede pasar?
>> Bueno, si todo de la entrada que el usuario tecleado no es sólo un amistoso
o una cadena de caracteres ofensiva.
En realidad es una secuencia de caracteres que si lo compiló,
lo que realmente es el código.
Tal vez es el código que se borren todos los archivos en su disco duro o envía correo no deseado
o algo por el estilo.
Tenga en cuenta que lo que es clave aquí es que si el malo de la película tiene la suerte de
sobreescribir el trozo rojo de la memoria -
lo que no me baso en mi imagen, pero esta foto Wikipedia tiene aquí -
su llamada remite.
>> Cuando vuelve la comida, cuando regrese el swap, ¿cómo sabe el ordenador para ir de
aquí a aquí abajo?
O en el segmento de tecnología por encima, ¿cómo Cómo sabe que ir a la permuta
código - del 0 y el 1 de que canje de redacción -
Regresar al Principal?
Hay una llamada dirección de retorno almacenada en el mismo marco de pila, en
la misma bandeja de cafetería.
>> Así que si el malo de la película es lo suficientemente inteligente como para poner código de ataque, el código de ataque, ataque
código, y obtener la suerte -
a menudo a través de ensayo y error - a sobrescribir ese remitente rojo,
con la dirección y el aviso la parte superior.
Observe 0835C080.
Ha escrito al revés encima de la tapa para razones por las que van quizás vuelven a visitar.
Este es ese número.
>> Así que si el malo de la película se pone la suerte o es lo suficientemente inteligente como para sobrescribir el rojo
tira de memoria con la dirección de código que él o ella tiene de alguna manera
inyectado en su computadora, adivinar cuya código va a ser devuelto a
tan pronto como foo se realiza la ejecución?
>> Lo malo del código tipo.
Así que este código de ataque, AAA, de nuevo, podría enviar correo no deseado, podría eliminar todos los archivos
en su disco duro.
Pero eso es lo verdaderamente un desbordamiento de pila es, o un desbordamiento de búfer, o una
ataque de desbordamiento de búfer.
>> Y es muy, muy común a este día con programas escritos en
C, C + +, e incluso algunos otros idiomas.
En ese sentido miedo, vamos a terminar con una broma.
>> [Risas]
>> Nos vemos el miércoles.
En la siguiente CS50 -
Así que me he quedado sin lámparas disco hoy, pero esperar, leche sin grasa, media el teléfono
libro, el jugo de naranja que bebí hoy.
Cable USB, una llave inglesa.
>> [REPRODUCCIÓN DE MÚSICA]