>> [Música tocando]
>> DAVID J. Malan: Todo ben que é CS50 e este é o inicio da semana, cinco.
Entón, hoxe, debaixo dos seus asentos, non vai atopar nada.
Pero, por riba, ten que atopalos, un pequeno sinal de nosa gratitude por
todo o traballo que puxo o Partido dos Quince.
Só ten que retirar o pequeno círculo no abaixo para comezar a xogar ao
resto da clase.
>> Entón, lembro que, ou saber que problema definido catro, que saíu este fin de semana,
implica a escrita de outro partido.
Pero esta vez, implica a utilización dun interface gráfica de usuario real, e non un
Interface textual como Xogo dos Quince era.
E o partido que está á fronte de ti, Se aínda non viu esta próxima,
parece un pouco algo así.
Eu estou indo a ir no meu terminal fiestra aquí en GDB.
E eu estou indo a ir adiante e executar o solución persoal, que pode acceder
tras a execución de actualización de 50 como de costume.
>> Pero eu vou poñelas un pouco xeito secreto, un pequeno ovo de Pascua,
o chamado modo de Deus, por poñendo Deus en argv1.
E eu teño que seguir os meus propios sentidos, executa-lo na miña propia
problema de establecer o directorio.
Entón agora ve unha versión completa do xogo de Breakout.
En realidade, este é o modo de non-man.
Polo tanto, é de feito -
empolgou que pode ser -
ben sinxelo de se aplicar o modo Deus no Breakout, a diferenza do xogo dos Quince,
que algúns de vostedes poden ter abordado para a edición de hacker.
>> En Breakout só en Deus xeito de simplemente facer o que,
intuitivamente coa pa?
Só facelo igual a calquera que sexa o posición horizontal é de balón.
E, sempre que faga iso acorde co balón en movemento este xogo vai
nunca, nunca, nunca perder o balón e vai gañar cada vez.
>> Pero, na edición de hackers esta semana hai máis que o modo de Deus.
Hai unha serie de outras características.
Entre eles, os láseres.
Así que se o estar impaciente lle Pode comezar a derrubar os ladrillos
e algúns outros.
E para aqueles de vostedes que quere calibrar estándar contra hackers
edición, podo ver que esta semana edición hackers deliberadamente é un
algo máis factible, por exemplo, que a Deus xeito foi con Game of Quince.
>> Entón, se está a buscar un fragmento e está a buscar un pouco de diversión adicional
características fan do mergullo en caso de interese.
Agora, máis práctico, déixeme ligar fora unha cousa así.
GDB, que algúns de vostedes poden non ter aínda tocou persoalmente, o que é bo.
Pero agora é realmente o tempo para acostumar esta e cómodo con esta ferramenta
porque vai facer a súa vida moito máis doado, realmente.
>> Por charla de Rob en GDB unha parella de semanas, lembre-se
que GDB é un depurador.
É unha ferramenta que permite que executa o seu programa, pero executa-lo paso a paso, liña
por liña, de modo que pode picar arredor, de xeito que ve as cousas a suceder, entón
que pode imprimir Os valores das variables.
En suma, dálle moito máis enerxía que printDef fai.
>> Agora é certo, a interfaz é moi misterioso.
Interface textual branco e negro na súa maior parte.
As ordes son un pouco difícil recordar en primeiro lugar.
Pero aínda que isto pode levar a metade unha hora, unha hora, para poñer ese adiantado
investimento de tempo para el, confíe en min.
Seguramente ata o final do semestre vai aforrar unha orde de magnitude máis
tempo.
>> Entón, a comezos da semana mergullar dentro
E en termos de Breakout, sabe que pode facelo, sempre que ten
o código de distribución ou de seu propio código en marcha no seu directorio Pst4.
Saber que pode realizar o gdb. / Fuga.
>> Isto abrirá unha fiestra como esta.
Deixe-me dar-me máis dunha fiestra de terminal.
E entón o que eu estou indo a ir adiante e facer, non é só executalo.
Vou primeiro definir un punto de ruptura recordo, o que permite que pause
execución nun lugar particular.
>> Só para manter as cousas simples que eu vou para romper a liña dun só escribindo
o número un.
Permítanme, en realidade, re-abrir esta xanela porque está quedando un
pouco pequeno alí.
Entón o que eu estou indo agora para facer aquí é se eu abrir a miña fiestra terminal.
Imos, alí imos nós.
>> Polo tanto, agora se eu volver a Dropbox, Pst4 e executa gdb. / fuga entrar, teña en conta
Vou romper un para axustar un punto de ruptura na liña un.
E agora estou indo a ir adiante e tipo de correr.
E cando o fago, notar nada parece pasar.
>> Non hai emerxente.
Non hai vídeo interface co usuario aínda.
Pero iso é comprensible, porque eu son literalmente na liña un no meu programa.
E noten que eu axiña encamiñados, especialmente agora a 62, porque todos
as cousas na parte superior deste arquivo é cousas como comentarios e constantes e
desinteressante cousas por agora.
>> Entón agora eu estou no inicio, ao parecer, na liña 62.
E esta é só a distribución código, recall.
Se eu abrir tanto, indo, do mesmo xeito, no meu directorio caixa de correo en Pst4,
en breakout.c.
E se eu rolar para abaixo e para abaixo e para abaixo, e deixe-me ir adiante e chamar
os meus números de liña.
>> O que eu vou ver se eu rolar para abaixo para liña 62, é exactamente a liña que
nós xa parou diante.
Polo tanto, esta liña aquí, 62 anos, é onde estamos a piques de ser.
Entón, agora en GDB, se eu ir adiante e escribir agora seguinte, entrar vai
executar esta liña.
E listo, temos a chamado xanela g.
Se non está familiarizado co que un GWindow é, non se preocupe.
A especificación ha presenta-lo a el, como así como un número de vídeos paso a paso
incorporado na especificación.
>> Pero agora imos facer este un pouco máis interesante.
Déixeme pasar esta fiestra sobre ao lado un pouco.
Deixe-me facer a xanela un pouco grande para que eu poida ver máis.
>> E agora déixeme ir adiante e facer logo de novo.
E alí están os meus ladrillos.
Se eu escribir xunto de novo agora vexo o balón.
E se eu escribir logo de novo agora vexo o remo.
>> E, por sorte, iso non é gedit realmente cooperando por me amosar
todo o que quero.
Pero agora, se eu fai a próxima vez, próxima vez, eu son só
declarar algunhas variables.
E podo imprimir calquera deses caras.
Imprimir ladrillos, gravados vidas.
>> E agora, se eu continuar a facer Logo, teña en conta que eu vou ser
dentro dese circuíto.
Que o código vai realizar exactamente como eu esperaba.
Entón, cando bati esta función, Espera para Preme, que fará
literalmente iso.
Entón, eu parecía perder o control sobre o programa.
>> GDB non está me dando outra ventá.
Pero non se preocupe.
Ir o meu xogo, preme en algún lugar.
>> E listo, agora pasa a liña 86.
Entón, de novo, é de valor inestimable, en última instancia, a problemas de depuración.
Porque pode, literalmente, percorrer o seu código, as cousas imprimir e moito,
moito, moito máis.
Pero de momento, estas ferramentas só deberá facelo moi lonxe.
>> Entón, nós estamos, por suposto, un ollo en gráficos, agora, de súpeto.
E agora o noso mundo está un pouco máis interesante.
E vostede sabe, se cadra, de algúns dos vídeos en liña que temos estes
bermuda que foi asistir como parte de conxuntos de problemas.
>> E eles foron tiroteados, deliberadamente, contra un fondo branco.
E algúns deles teñen o ensino Fellows deseño algún texto en
pantalla que é sobreposto no lado deles.
Pero, claro, isto non é todo o que interesante no mundo real.
Esta é só unha clase cun gran pantalla branca e un pano de fondo.
E a nosa incrible equipo de produción tipo de fai todo parecer bonito
despois do feito cortando fóra ou superposición de calquera cousa
o que facemos ou non quere.
>> Agora é só para motivar esta semana e realmente, onde pode ir, en última instancia,
coa ciencia da computación.
Non só despois problema establecer catro.
Pero despois de outro curso ou conxunto currículo é impresionante o que pode
facer a día de hoxe en termos de gráficos, en particular.
>> Algúns de vostedes poden ter visto iso flúe arredor liña.
Pero eu penso que eu ía mostrar, por só un uns minutos, un reflexo do que
informática e que CGI, computación gráfica pode facer a día de hoxe
cunha canción familiar e quizais a película.
>> [Music - La DEL RAY, "Novo e bonito]
>> COLUMNA 1: É un pouco sorprendente, quizais, o no;
omnipresente -
>> [Aplausos]
>> COLUMNA 1: Eu só baixei.
Pero é realmente incrible, eu creo, só como o software omnipresente e código e
ferramentas como esta son realmente.
Entón, iso é un gusto da dirección en que pode ir.
Oh, non máis Appliance hoxe.
Ben, iso é tempo realmente tráxico dado o momento que eu só tente facer.
>> Todo ben, entón imos publicar Fusión de novo.
Lembre me máis tarde.
Todo ben, e ten que conseguir un enviar correo-e como un aparte, se non obter un
entender como ese.
Todo ben, entón lembrar que a semana pasada comezamos a pelar este
máis tarde coñecido como cadea.
>> cadea lembra un tipo de datos que se declarados na biblioteca CS50.
E é parte das Rodas pequenas que agora vai comezar a despegar.
Era un concepto útil no inicio.
Pero agora se ve máis interesante e máis potente para
realmente ver que debaixo do capó, unha cadea é só o que, non podemos dicir?
>> Si, por iso é un chamado char *.
E o * non denota que non hai algún tipo de enderezo implicados.
E así, cando di char * que acaba de dicir unha variable cuxo tipo de datos é un
punteiro agora.
O feito de que hai a estrela alí Significa só que está declarando unha
así chamado punteiro.
E ese punteiro vai parecer almacenar a dirección, de
Por suposto, un char.
>> Agora, por que isto ten sentido?
Ben, o que é unha cadea debaixo do capo?
Ben, hai tempo que veño dicindo que unha corda debaixo do capó é
só h-p-l-l-o, por exemplo.
>> Pero nós xa falamos sobre isto como ser, esencialmente, unha matriz.
E unha matriz, entón, mirar un pouco máis como este, con cada un destes
ocupando unha mordida.
E entón nós dixemos que non hai algo especial para acá, o
barra invertida 0, ou terminador nulo.
>> Entón todo este tempo, que aquí foi unha cadea.
Pero, en realidade, unha cadea é en realidade, un enderezo.
Enderezos, como veremos, moitas veces son prefixado con 0x por convención.
Que 0x denotar?
Alguén sabe?
>> Entón, iso significa só hexadecimal.
Entón, ten que lembrar, en realidade, a partir de PST 1, eu creo, unha das warm-up
cuestións realmente lle preguntou notación hexadecimal ademais
binario e decimal.
E o que é aquí motivación con hexadecimal ten 16
díxitos á súa disposición.
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, seguida por a, b, c, d, e, f.
>> E se contar todos aqueles por riba, recibe un total de 16.
Así, isto está en contraste coa decimal, onde temos 10
díxitos, 0 a nove.
É, en contraste co binario onde temos só 0 e 1.
>> Pero ao final do día, pode só representan os mesmos números, pero
un pouco diferente.
E hexadecimal é común porque, como acontece que - e imos ver iso
máis tarde no curso - mesmo cando chegamos a programación web no contexto da
HTML e código de cores, hexadecimal é bo.
Como cada díxito, botan, representa catro bits perfectamente.
Por iso, só unha especie de liñas ata ben como imos finalmente ver.
Entón, isto pode ser Ox123 ou algo así, denotando dirección 123
nalgún lugar dentro do meu memoria do ordenador.
>> Pero, por suposto, xorden algúns problemas debido a esta subxacente
implementación.
E lembro que eu levei unha facada implementación dunha función como esta -
comparar trazo 0 punto c a semana pasada, que aínda que parecía que era
dereito, el simplemente non comparar dúas cordas correctamente.
>> Eu xoguei fóra principal, e eu xoguei aínda que os comentarios só para concentrarse en
o código que é de interese aquí.
E é en vermello porque é buggy.
Por que?
>> Así, na parte superior alí cando eu declarei unha corda, o que realmente estaba a suceder
debaixo do capo?
Ben, deixe-me ir ao pantalla aquí e chamar a iso.
Entón eu dixo, unha vez máis, GetString cadea s.
>> Entón, eu estou indo a ir adiante agora e deseñar s para o que realmente é.
Vai ser unha praza aquí.
E eu vou reclamar que isto é 32 bits.
Polo menos é xeralmente, polo menos na CS50
aparello en unha morea de ordenadores.
Vou chamalo s.
>> Pero, agora, recordar que nos chamado GetString.
Retorno Entón GetString, suposto, unha cadea.
O usuario escribe h-e-l-l-o entrar a cadea Ola será devolto.
E esa cadea, como acabamos de dicir, remata nalgún lugar na memoria do seu ordenador
0 cunha barra invertida ao final.
Vou tomar isto como a matriz - ou bloque contiguo de personaxes -
que realmente é.
>> E agora, o que é GetString realmente volvendo?
Cal foi getString volver todo este tempo?
Así, podemos dicir, a semana anterior, el retorna un cadea.
Pero, máis tecnicamente, o que fai GetString retorno parecer?
>> Audiencia: un enderezo.
>> COLUMNA 1: Un enderezo.
En concreto, el retorna o enderezo de a primeira mordida, sexa cal sexa.
Eu segue a usar un, dous, tres por que é cómodo.
>> Devolve o enderezo do primeiro carácter na secuencia.
E nós dixemos a semana pasada que que é suficiente.
Porque sempre podemos descubrir que o fin da cadea só por
iteración sobre iso, quizais, coa loop ou un loop while ou algo así
que, só de ollar para "barra invertida 0", o carácter sentinela especial.
>> E entón sabemos que a cadea pasa a ser de lonxitude -
neste caso -
cinco.
Entón, tecnicamente o que fai GetString é el retorna Ox123 neste caso.
E tecnicamente o que pasa entón é que nos gardamos, dentro s, Ox123.
Ao final do día, aínda que esta é concepto novo, punteiros, son
só variables.
Pero eles acontecen para almacenar bits que colectivamente representan un enderezo.
Entón, tecnicamente todo o que queda almacenado s é Ox123.
>> Pero nós, como seres humanos -
ata hoxe en diante -
son realmente non vai importar, normalmente, cal é o enderezo real é
dalgún anaco de memoria.
É só a baixo nivel de detalle para ser intelectualmente interesante.
Entón, eu estou indo a desfacer iso.
E, ao contrario, máis alto nivel, só tes que dicir que cando estamos a falar de punteiros
Vou só chamar máis frecha amigable que transmite a
mesma idea e abstrai os indicación de que o real
enderezo subxacente.
>> Agora, se volver para o código, o que sucedeu a semana pasada, se temos corda t
igual GetString?
Ben, se eu de novo, escriba Ola esta vez eu vou conseguir
outro anaco de memoria.
h-p-l-l-o invertida 0.
>> Pero por que eu chamei GetString por segunda vez -
e sei que isto de mirar o fonte para GetString - aínda
pero é coincidencia que Ola foi ingresaran dúas veces, GetString non é
tratará de optimizar e ser intelixente.
El só vai pegar outro anaco de a memoria do ordenador, que está
será noutro enderezo.
Nós só dicir arbitrariamente 456.
>> E entón o que é o que vai volver?
Volverá 456 e almacena-lo en t.
Entón, o que realmente está a suceder, sobre o á esquerda, é que eu teño un outro anaco
de memoria de 32 bits normalmente.
E alí está a ir Ox456.
Pero, de novo, eu non estou interesado nestes números específicos tecleamos máis.
Eu só vou abstractamente deseña-lo como unha frecha.
>> Polo tanto, esta é agora unha nova explicación.
Pero é exactamente a mesma idea que se ven a suceder todo este tempo.
E así, a razón, entón, que esta primeira versión de comparación foi buggy
a semana pasada, e por que?
Cando se s é igual a igual t O que está verdadeiramente
debaixo do capó comparando?
>> Está comparando os enderezos.
E, así, intuitivamente, claramente, Ox123 non vai igual Ox456.
Eses números, eses bits son só diferentes.
>> E así, de forma consistente, a semana pasada, el dixo escribe cousas distintas, aínda que a
palabras foron literalmente o mesmo.
Entón imos solucionar isto.
En termos leigos, o que era a corrección?
>> Audiencia: Use unha función.
>> COLUMNA 1: Usar unha función.
Ou estrelas están sempre implicados, pero usar unha función para facer o que?
>> Audiencia: Para comparar as cordas.
>> COLUMNA 1: Para comparar as cordas.
Así, o problema fundamental aquí foi que eu estaba só tendo en conta a
calidade de corda a ser definido pola comparación dos seus enderezos.
E, por suposto, iso é só mudo agora xa Entende o que está pasando
debaixo do capó.
Para comparar verdadeiramente cordas a ver se son iguais na forma que un ser humano
consideraría dúas cordas para ser igual hai que comparalos-los carácter para
personaxe para personaxe.
>> Agora eu podería ter feito esta moi tedioso.
Pero familiarmente, estamos usando un loop for.
E basta comparar s soporte i contra t soporte i.
s soporte de i + 1 contra t soporte i + 1, e así por diante, para dentro
unha especie de loop.
E se eu detectar calquera dous personaxes que diferentes, ou se eu entender que ooh, s é
máis curta do que te ou máis que te Podo dicir inmediatamente falso,
eles non son o mesmo.
>> Pero se eu pasar s e t e dicir mesmo, mesmo, mesmo, mesmo, mesmo, a fin de
ambas as cordas, o que podo dicir realidade, son iguais.
Ben, por sorte, anos atrás, alguén escribiu que o código para nós.
>> E eles chamaban tanto SeqComp a cadea de comparar.
E aínda que sexa un pouco contra intuitivo, StrComp retorna 0 se os
dúas cadeas, s e t son o mesmo.
Pero el retorna valor negativo se s debe vir antes de t en orde alfabética ou
valor positivo se debe vir despois de t en orde alfabética.
>> Entón, se quere resolver algo, verifícase que SeqComp é útil.
¿Por que non basta dicir si ou non, iguais ou non.
El lle dá un sentido de ordenación como unha forza dicionario.
Entón SeqComp, s coma t é igual a é igual a 0 significa que o
cordas son verdadeiramente iguais.
Porque quen escribiu esta función anos, presuntamente usado un loop
ou un loop while ou algo así para integrar máis os personaxes de novo
e de novo e de novo.
>> Pero dous problemas xurdiron aquí.
Este foi copy0.c.
E os dous está en vermello por que é fallo.
E o que facemos aquí?
Ben, primeiro eu chamei GetString.
E eu gardei o valor de retorno en s.
Entón, iso é practicamente o mesmo que esta parte superior da imaxe.
>> Pero o que vén despois diso?
Ben, deixe-me ir adiante e librarse unha morea de presente.
Imos volver o tempo para onde nós só ten s, que agora é consistente coa
unha liña alí enriba.
>> Eu verifico.
Si s é igual é igual a 0.
Agora, unha nota lateral rápido cando GetString pode devolver 0?
Non hai memoria suficiente.
Non?
>> É raro que iso vai ocorrer, seguramente nun ordenador que está
ten centos de megas ou mesmo GB de RAM.
Pero podería, en teoría, o regreso 0, sobre todo se o
usuario non cooperar.
Hai formas de finxir que non ten algo escritas e truco
GetString en voltar 0 eficaz.
>> Entón vai para buscar iso.
Porque se algún de vós xa comezaron a se, xa, fallos de segmentación -
que probablemente foi unha fonte dalgunha frustración -
estes son case sempre o resultado de erro relacionado coa memoria.
Dalgunha forma, romper todo no que se refire a un punteiro, mesmo se non entender
houbo un punteiro.
Entón vostede pode ter inducido a segmentación defectos tan cedo como unha semana a usar
algo así como un loop ou un tempo loop e unha matriz por ir lonxe de máis
alén dos límites da matriz que algúns vostede declarou, en dúas semanas, en
particular.
>> Pode ter feito isto mesmo problema establecer catro con Breakout.
Aínda que probablemente non viu ningunha estrela no código de distribución para
Breakout, verifícase que os GRect e Goval e outras cousas que tales,
estes son realmente os punteiros debaixo do capó.
>> Pero Stanford, coma nós, tipo de pel este detalle, polo menos para as bibliotecas
propósitos, moi parecido ao que facemos a cadea e char *.
Pero GRect e Goval e de todos aqueles cousas que están ou estarán a usar
esta semana son en definitiva, enderezos de memoria.
Vostede simplemente non sabe.
>> Polo tanto, non é sorprendente, entón, se cadra, que se pode tropezar nalgún
fallos de segmentación.
Pero o que é interesante aquí agora, Se despois de comprobar 0 que facemos
corda t queda s.
Ben, déixeme declarar t.
Vou deséñase como un cadrado, 32 bits, chamalo de t.
E entón eu vou facer se s.
>> Ben, o que significa isto?
Ben, é algo difícil pensar niso imaxinar sabio.
Pero imos pensar sobre o que está dentro de x?
Que é, literalmente, dentro desa variable?
O valor Ox123.
>> Polo tanto, cando digo corda t queda s, que literalmente significa ter o número
en s, que é Ox123 e poñelas Ox123.
Ou pictoricamente, se eu tipo de abstracto lonxe dese detalle ten o
efecto de literalmente facer iso tamén.
>> Entón, agora, creo que volta a semana pasada, cando procedeuse se capitalista T. I
fixo T soporte 0.
Ben, T apoio 0, aínda que sexa un punteiro, pode trata-lo como se
é unha matriz, cun cadrado notación soporte.
>> Entón, onde está T soporte 0?
Ben, é o h.
E así, cando usamos esta liña de código, dous máis, que está en que c type.h
ficheiro de cabeceira, que é onde é declarado.
Está capitalizando este H. Pero, Por suposto, iso é exactamente o mesmo que h é
s no interior, por así dicir.
E agora cambiou ou capitalizar tanto o orixinal eo
chamado copia.
Porque non fai unha copia na forma que un ser humano quere que sexa.
>> Entón, cal foi a corrección aquí, en copy1.c a semana pasada?
Funcións, para que poidamos realmente copiar o cadea.
E, fundamentalmente, o que necesitamos facer a copia a secuencia?
>> Pois ben, nesta versión verde aquí estou vai facelo moi baixo nivel.
En realidade, hai funcións poderían axudar con iso.
Pero o máis básico eo máis un familiar, polo menos, en breve será
familiar para nós, é o seguinte -
así un na primeira liña do código en verde agora.
>> Só reescreveu s como char *.
Non hai ningún funcional diferenza alí.
Eu só xoguei fóra a biblioteca e CS50 Estou chamando-o que é, un char *.
>> Agora, punto, punto, punto, porque non había comprobación de erros que non é
interesante para falar de novo.
Entón, agora t é declarada.
El tamén é un char *.
Entón eu deseño dunha pequena praza en a pantalla como antes.
>> Pero, no lado dereito, malloc, dixemos é reservar memoria.
Entón reservar algún anaco de memoria.
E cantos bytes é que imos realmente desexa asignar, non parece?
>> Así, a lonxitude da cadea de s.
Entón, se é que é Ola será cinco.
Digamos h-e-l-l-o.
Así, cinco bytes.
>> Pero, entón, unha, por 1?
O 0 personaxe.
Se non deixar espazo para este cara que accidentalmente pode crear unha situación
onde a corda é h-e-l-l-o.
E, a continuación, a próxima vez é GetString chamou e eu escribir, por exemplo,
David, D - v-i-d, o ordenador vai pensar que s é realmente
h-p-l-l-o-d-a-v-i-d, porque hai sen pausa entre as palabras.
>> Por iso, necesitamos que pausa.
Entón, non queremos que cinco.
Queremos seis bytes.
>> E bytes que digo.
Pero é o tamaño realmente o tempo do char.
Tecnicamente char é case sempre un byte.
>> Pero só para facer o noso código portátil, por así dicir, de xeito que funciona en
ordenadores diferentes, aínda se poden ser un pouco diferente por baixo do
capa, vou xenericamente dicir o tamaño do char para que
meu código sempre funciona.
E eu non teño que recompilar só por que eu actualizar meu ordenador ou utilizar
unha plataforma diferente.
>> Entón eu teño seis veces o tamaño da un char, que pasa a ser 1.
Entón iso significa que malloc podería me dea seis bytes.
Que realmente está facendo?
Ben, deixe-me retroceder o tempo aquí onde estamos na historia.
>> Entón, se eu volver aquí, eu xa declarou un char * chamado t.
Eu xa chama malloc por seis bytes.
E agora eu vou chamar os seis bytes así como a matriz anterior.
Pero eu realmente non sei o que é dentro desa matriz.
>> Se reservar memoria verifícase que non se pode confiar en que hai algún
valor coñecido alí.
Podía ser utilizado por algo outro, outra función, outra
liña de código que escribiu.
Entón, imos chamar estes xeralmente lixo valores e deseña-los, se cadra, como
puntos de interrogación, indicando só que non sei o que está realmente alí.
E iso non é gran cousa con tal de que son intelixentes o suficiente para substituír os
valores de lixo con números ou caracteres que se preocupan.
>> Polo tanto, neste caso o que vou facer?
Ben, a miña liña de código seguinte, eu teño catro.
int i obter 0, n recibe o lonxitude da corda de s.
Así, un familiar ao loop.
I é menor ou igual a n, que é xeralmente enriba.
>> Pero esta vez é deliberada.
I + +, e entón eu simplemente facer t soporte i queda s.
Porque a miña imaxe se parece iso a Neste momento, almacenado en que t é o
dirección desta peza aleatorio de memoria cuxos valores son descoñecidos.
Pero así que fago t soporte 0 que me pon aquí.
>> E o que acaba sendo atraídos para alí?
Nós acaban poñendo h.
Porque iso é o que está en s soporte 0.
E, a continuación, o mesmo para e e, l, l, e o.
>> n, polo que vou cara arriba a través igual a n?
Debido ao seu carácter 0.
Entón, só para quedar claro, entón, se realmente borrará todo o que estes lixo
valores e entón realmente atraer o que eu espero, é s pista 1, 2,
3, 4, ademais de que é á dereita novo personaxe.
>> E agora si continuássemos pasado do punto, punto, punto nesta versión correcta
e capitalizar t soporte 0 eu ía, de Por suposto, se aproveitando só iso
cara aquí e que, conceptualmente, resultou ser a meta.
Entón, iso é todo o punteiro está.
>> E ten de usalos por semanas Agora, no contexto de cadeas.
Pero debaixo do capó son un pouco máis complexa.
Pero se pensar sobre eles neste forma pictórica propoño que son
probablemente non é tan asustado como primeiro pode parecer a primeira vista,
particularmente con esa nova sintaxe.
Calquera dúbida sobre punteiros, cordas, ou chars?
Si?
>> Audiencia: Pode volver a [inaudível]?
>> COLUMNA 1: Claro.
>> Audiencia: Entón como é que na súa última liña, non ten unha liña de t *
e * s en liña?
Non ten a referencia ao -
>> COLUMNA 1: Ah, unha pregunta moi boa.
Por que eu non teño a * t * e unha s?
Por un intre, a semana pasada, como no noso función de cambiar, eu dixen que cando
ten un punteiro o medio polo que vai alí, como fixemos
fisicamente o escenario, era, en realidade, usar o operador estrela.
>> Acontece que esta de corchetes notación é a que imos chamar sintática
azucre, que é só un xeito sexy de dicindo que é notación abreviada para
exactamente o que está describindo.
Pero é un pouco máis intuitivo.
E correndo o risco de facelo parecer máis complicado do que ten que ser,
o que realmente está a suceder aquí é o seguinte -
Se eu digo * t que significa ir a dirección almacenado en t.
>> Entón, literalmente, se t está almacenando a dirección desa h
Inicialmente, a * t medio aquí.
Agora o que te soporte 0 significa?
Mesmo.
É só algo máis user agradable para escribir.
>> Pero eu non estou preparado aínda.
Non podo simplemente dicir * t * s queda.
Porque o que eu estaría facendo entón?
Eu estaría poñendo h, h, h, h, h toda a cousa toda.
Non?
>> Por * t é ir ao enderezo en t.
Pero estamos dentro dun loop.
E cal é o valor que eu estou incrementando, suposto, en cada iteración?
i.
>> Pero hai unha oportunidade aquí, non?
Aínda que iso parece que está quedando algo máis sofisticadas
que a notación de corchetes temos usado por algún tempo -
déixeme desfacer a miña cambio de h alí -
aínda que iso agora está quedando un pouco extravagante, a idea básica, se * t
significa aquí e * t é só ir ao enderezo de t.
>> Pero cal era o enderezo no t?
O número que seguir a usar?
Como Ox456, imos traer iso de volta só por unha cuestión de debate.
Ben, se eu queira chegar ao e en t cadea, eu só quero ir,
esencialmente, 456.
>> Ou mellor, 457.
Eu só teño engadir unha.
Pero eu podo facelo, non?
Porque t, a pesar de eu manter deseño agora como unha frecha, é só un
número, Ox456.
E se eu engadir un para iso, ou máis xeralmente, se eu engadir I para que eu poida
realmente chegar exactamente onde quero.
Entón, se eu realmente facer iso -
e iso é o que se chama agora punteiro aritmética -
Podo eliminar esta liña.
Cal é, francamente, creo que máis clara e un pouco máis agradable para ler.
Pero isto non é menos correcto.
>> Esta liña de código está a usar agora aritmética de punteiro.
Está dicindo que ir ao seguinte enderezo -
calquera que sexa o inicio do t, que t é máis i, que inicialmente
é 0, o que é óptimo.
Porque o que supón o inicio do t máis 1, máis 2, máis 3, e así por diante.
E o mesmo con s.
>> Entón azucre sintático para iso.
Pero a comprensión do que realmente está a suceder debaixo do capó, eu diría,
é realmente útil en si mesmo.
Porque iso significa que agora non hai moito máis maxia suceder
debaixo do capó.
Non van ser moitos máis capas que podemos descascada para ti.
Este é c.
E esta é a programación.
Pregunta moi boa.
>> Todo ben, entón iso foi que de buggy programa que eu estaba me referindo anteriormente.
troco foi fallo.
Se parecía funcionar.
Lembre que, como con leite e o zume de laranxa - que comece a
dí manifestación de hoxe.
Así como co zume de laranxa e o leite, que tivo que usar unha
variable temporal, tmp, para realizar unha temporalmente, para que puidésemos entón
modificar o seu valor e, a continuación, actualizar b.
>> Pero esta función, como dixemos, é esta programa no que esta función é
escrito estaba mal e fallo, por que?
Si?
>> Audiencia: [inaudível].
>> COLUMNA 1: Exactamente cando vostedes chaman de intercambio -
ou, máis xeralmente, cando chamar máis calquera función -
os argumentos para esa función son primitivas, por así dicir, ints e chars
e dobres e Carrozas, as cousas sen estrelas, está pasando unha copia do
o argumento.
Polo tanto, se x e y era unha era de 2, un vai sendo 1 eb será 2.
Pero eles van ser diferentes anacos de bits, diferentes bloques de
memoria que veñan a ser almacenando valores idénticos.
>> Polo tanto, este código é super perfecto a cambio de a e b.
Iso non é bo en cambio -
no exemplo da semana pasada -
xe y.
Porque unha vez máis, son no ámbito incorrecto.
>> Agora, como é que nós imos sobre a fixación iso?
Tivemos que facer a función mirar un pouco máis feo.
Pero, de novo, considerar o que isto significa só.
>> E, de feito, deixe-me, por coherencia, cambiar unha cousa así que é o mesmo que o
o que nós fixemos.
Cómo mencionen a semana pasada, el non importa a onde vai.
De feito, normalmente ía poñer o estrela á beira do nome da variable.
Pero eu creo que sería un pouco máis fácil considerar a * xunto da
tipo de datos que quere dicir que é un punteiro para un int neste caso.
>> Entón, o que eu estou facendo aquí?
Eu digo que non me dea un int seguido por outro int
chamando-os de a e b.
Dáme o enderezo dun int.
Dáme a dirección doutro int.
Chama quen aborda a e b.
>> E, a continuación, usando a notación * abaixo a continuación, vai a cada un destes enderezos
sexa necesario para obter calquera ou establecer o seu valor.
Pero hai unha excepción aquí.
Por que eu non teño un * xunto tmp?
Por que eu non fago iso, por exemplo?
Parece que eu debería ir todos fóra e corrixir a cousa toda.
Si?
>> Audiencia: [inaudível].
>> COLUMNA 1: non declarei tmp como unha cadea.
Polo tanto, este debe establecer, neste caso, un tmp para ser o enderezo dun int.
Pero isto non é así o que quero, por un par de razóns.
>> Audiencia: Non quere trocalos.
>> COLUMNA 1: Exactamente, eu non quero cambiar nada con tmp. tmp é só
De semana unha cousa.
Todo o que quero é unha variable para almacenar un número.
Eu non me importa sobre enderezos neste momento.
>> Eu só teño de 32 bits ou para almacenar un int.
E quero poñer nestes 32 bits todo o que non está nunha, por así dicir, pero
o que está en un, só para ser máis preciso.
Porque se un é un enderezo *, un medio ir alí e obter o valor 1.
Por exemplo, o exemplo da semana pasada ou no caso de b, obter o valor de 2.
>> Entón, o que está realmente a suceder?
Déixeme aproveitar unha foto aquí que vai só desmembrar parte hoxe.
Pero isto vai continuar a aparecer por algún tempo.
>> Iso, eu afirmo, é o do seu ordenador memoria parece que cando realizar un
programa, calquera programa.
Cando fai un programa na parte superior de memoria RAM do seu ordenador - para pensar
este rectángulo, verdadeiramente, como o seu RAM ou a memoria do ordenador, as 101
mil millóns de bytes dela, todos de dous millóns de bytes, as dous gigabytes de que,
calquera que sexa a cantidade que ten é, imos deséñase la como un rectángulo.
E eu afirmo que cando executar un programa como Microsoft Word ou Chrome
ou algo así, os bits que Microsoft ou Google que escribiu -
nos casos dos devanditos programas -
son cargados na memoria do seu ordenador onde poden ser executados máis
rápido e alimentados na CPU, o que é o cerebro do ordenador.
>> E na TAM están almacenados no propio parte superior do seu programa, por así dicir.
Noutras palabras, se este é un anaco de memoria, cando fai clic dúas veces sobre
Microsoft Word, os bits chegar fóra do disco duro.
Son cargados na memoria RAM.
E nós imos empurra-los cara arriba na parte superior dese rectángulo conceptualmente.
>> Ben, o resto da súa memoria é usado para cousas distintas.
Na parte superior ve arrincar datos e uninitialize datos.
Isto ten que ver, en gran parte, coa constantes ou variables globais
que teñen valores.
Pero máis sobre quen outra vez.
>> Así que ten a pila, que imos volver.
Pero no fondo é a parte que se particularmente pertinente neste momento.
É o chamado pila.
Así como en máis ningunha sala D aquí en campus, ten aquelas bandexas que
só apilar uns sobre os outros en que pode pór alimentos e outros enfeites.
A pila nun sistema informático é moi semellante.
Excepto mentres a bandexa, como usan en o comedor, claro, enténdese
para levar as cousas as bandexas ou os cadros -
como imos chamalos - nun ordenador de memoria é usado para almacenar
variables e valores.
>> Entón, o que realmente pasa debaixo do capo?
Ben, deixe-me virar á pantalla aquí.
E imos concentrar só no parte inferior por un momento.
Se isto é a porción inferior da miña memoria do ordenador ocorre cando
chamar a función principal - que pasa, a verdade,
automaticamente para min -
Recibe un bloque de memoria no fondo da miña memoria RAM por así dicir.
E é aí principal variables locais ir.
É onde argc e argv quizais ir, e todas as variables I
declarar no inicio.
Eles acaban no fondo RAM do meu ordenador.
>> Agora, supoña que o principal chama unha función como intercambio, como fixo a semana pasada?
Ben, esencialmente, poñer un novo taboleiro, un novo marco, no meu anaco de memoria.
E eu vou describir isto como pertencentes á función intercambio.
>> Agora, o que está dentro de intercambio?
Así, con base no programa da semana pasada e o que acabamos de ver un fragmento,
dentro da estrutura de intercambio ou troco bandexa, o que son variables?
Ben, a e b.
Porque aqueles eran os seus argumentos locais, ademais dun terzo, tmp.
Entón, en realidade, eu podería debuxar ese un pouco máis limpa.
Déixeme ir adiante e desfacer o rótulo.
E deixe-me dicir que vostede sabe o que?
>> un probablemente vai acabar aquí.
B vai acabar aquí.
E tmp vai acabar aquí.
Agora, a orde pode ser un pouco diferente.
Pero conceptualmente esa é a idea.
>> E só colectivamente, isto é o que imos chama-estrutura de intercambio, ou
bandexa de comedor.
E o mesmo co principal.
Pero eu non vou redeseñar iso.
Pero é aí onde argc e argv e calquera das súas variables locais, como x e y
Pode ser así.
>> Entón agora considerar o que realmente está a suceder cando chama intercambio.
Cando chama intercambio, o código executado como tanto, está pasando, o
versión con erros, a e b como unha copia de xe y.
Entón, se fago agora deseñar ese na pantalla -
ten que ir mellor con iso -
así a historia que eu estaba dicindo para min mesmo Nesta versión con Bugs, cando
chamar intercambiar pasando literalmente a eb como enteiros, o que está realmente a suceder?
>> Ben, o que está realmente a suceder é iso.
Déixeme ir adiante e desfacerse só para borrar un espazo aquí.
Polo tanto, esta é a memoria do meu ordenador.
>> Entón, se eu tivera, por exemplo -
de feito, imos facelo deste xeito -
se eu afirmar que esta é x, almacenando o valor 1, así como a semana pasada.
E dicir y, almacenando o valor 2 así como na semana pasada.
E isto é o principal, cando eu chamo intercambio, dándome, así, o acceso a un e
b e tmp, vou afirmar que este é un e este é un.
>> Este é b.
Esta é 2.
Isto chámase tmp.
>> E, inicialmente, ten algún valor lixo ata que realmente gardar nel un,
que é 1.
Entón eu vou adiante e cambiar sendo o que?
Valor de B.
>> E agora eu teño dous aquí.
E entón nós dixemos b queda tmp.
Unha vez máis, así como unha comprobación de sanidade, a terceira liña de código aquí é simplemente isto
a, b queda tmp.
>> E así, por fin, o que fago?
Eu vou adiante e cambiar b para ser o que o valor de tmp é, o que é un.
Non toco tmp novo.
>> Pero agora, o problema é que así como intercambio volve, porque non está entregando
volver algún valor, non hai volta instrución explicitamente nela.
O que está realmente a suceder?
Ben, esencialmente, todo isto de memoria -
OK, ao parecer, a goma gusta só un dedo de cada vez -
simplemente desaparece.
>> Agora, en realidade, non é vai a sitio ningún.
Pero pode pensar niso agora, como puntos de interrogação.
Porque non é máis realmente en uso.
E nada é feito con eses valores.
>> Así, no caso da versión verde este código, que está a ser, en vez
pasou para intercambio?
Entón resolve.
Así, o seu enderezo de xe o enderezo do y.
Entón, se nos re-contar a historia dun pasado tempo, e eu realmente chamar o intercambio de novo,
pero con punteiros, sendo este un, é dicir sendo b, e sendo esta tmp, o que é
realmente almacenados nun nesta verde versión do meu código onde estou pasando
en enderezos?
>> Será un punteiro para x.
Entón, eu podería debuxar unha frecha.
Pero imos empregar o mesmo arbitraria exemplo, como antes.
Digamos que se trata algo así como Ox123.
E iso será Ox127 porque é catro bytes para lonxe, porque é unha
Cont, tan Ox127.
>> E de novo, eu estou tomando algunhas liberdades cos números.
Son moito menores do que sería e, de feito, ser nunha orde diferente.
Pero é así que a imaxe agora é diferente.
>> Pero cando eu uso este código verde e eu int tmp conseguir * a.
* Un medio para facer o seguinte, tome a resolver iso nun e ir a el,
que é 1.
E iso é o que eu, logo poñer en tmp.
Mentres tanto, na seguinte liña de código aquí, * a recibe b, o que significa isto?
>> Ben, * a, polo que aquí queda * b, o que significa ir máis alá.
E isto significa poñer o valor alí.
Finalmente, a última liña de código dixo simplemente * b recibe tmp.
>> Entón b di para ir alí e substituílo con tmp que, neste caso, vai
a ser, de novo, 1.
E é por iso que a versión verde de nosas obras de código, mentres que o vermello
versión nunca fixo.
Todo isto só se reduce á forma como o memoria é xestionada e onde se
realmente colocado no seu RAM do ordenador.
E, polo de agora, iso é unha das cousas que a pila está a ser utilizado.
>> Preguntas sobre o esquema?
En punteiros?
Ou no intercambio?
>> Todo ben, entón malloc, aviso, fixo algo parecido a isto.
Este foi un super exemplo simple.
E iso foi o que Binky nos presentou, aínda que moi
axiña, ao final da clase.
Drogas, alí imos nós de novo.
>> Entón, lembrar que este foi o exemplo que Binky nos presentou, aínda
un tanto rapidamente ao final da clase.
E aquí usamos malloc realmente , Por segunda vez.
Porque a primeira vez que se usa para crear RAM suficiente, reservar memoria RAM suficiente
para almacenar unha cadea.
>> Esta vez Binky mantivo simple.
Entón é para gardar só un int, aparentemente.
E iso é totalmente bo.
É un pouco raro, a verdade, a empregar malloc para reservar un int.
Pero o punto de claymation do Nick foi realmente só contar a historia do que
ocorre ou non pasa cando vostede maltratar memoria.
>> Polo tanto, neste caso, este programa fixen algunhas cousas.
No primeiro caso, aquí, que declara un punteiro chamado x para un int.
A continuación, el declara un punteiro chamado y para un int.
Logo almacena en x, o que?
Alguén agora.
O que queda almacenado en x de acordo coa a terceira liña deste programa?
>> Audiencia: [inaudível].
>> COLUMNA 1: Ben, non exactamente bytes, por así dicir.
Ser máis preciso momento.
O que queda almacenado x?
Un enderezo, creo que oín-lo.
>> Entón, o que malloc voltar?
malloc aloca comportamentalmente unha peza de memoria.
Pero como iso dálle acceso a el?
El retorna o que?
O enderezo do primeiro byte no anaco de memoria.
>> Agora, iso é super sinxelo.
É só un byte, o que significa que o abordar estamos quedando atrás é o
enderezo da cousa toda.
Entón almacenado en x, entón, é o enderezo dese anaco de memoria.
Mentres tanto, o que pasa?
Entón, en realidade, imos adiante e chamar iso moi rápido.
>> Entón, se pasar á pantalla aquí e imos xogar tanto int * xe y int *
vai facer o que para min?
Eu afirmo que el só vai facer algo como isto e chamalo de x, e
isto e chamalo de y.
Mentres tanto, a terceira liña de código é vai afectar o tamaño dun int
que pasa a ser - desculpe se eu dixese un antes de que eu quería dicir un int -
catro bytes nun ordenador típico.
Polo menos co aparello CS50.
>> Entón, que vai reservar , Quen sabe?
Nalgún lugar por aquí.
E esta é almacenada nalgún enderezo de Boi, quen sabe?
Pero o que está a suceder para volveuse é ese enderezo.
Pero imos sacar isto pictoricamente só como unha frecha así.
>> Agora, na seguinte liña * x recibe 42.
Que * x significa en termos laicos?
Só tes que ir alí.
Ir a este enderezo.
Ou, por outras palabras, a continuación frecha e poñer 42 alí.
Pero entón algo de malo aconteceu a Binky, non?
>> Lembre-se de que a liña de cinco aquí, * y recibe 13, en realidade unha serie de azar,
fixo o que para nós?
Ben, * y significa ir ata alí.
Ben, este non foi dada aínda un valor, non?
O código non ten y sendo inicializar para nada.
Tiñamos x ser inicializar a un enderezo.
Pero y foi declarado enriba.
Pero, entón, un punto e coma, sen valor foi realmente poñer sobre el.
Polo tanto, é xusto chamar esta un valor de lixo.
Quen sabe o que é?
Son os restos de bits que foron utilizados por algunha liña de código anterior en
meu programa.
>> Entón, se eu digo que ir alí, iso é como, Eu non teño ningunha idea de onde esa frecha é
vai acabar.
E é aí que normalmente obter un fallo de segmento.
Se accidentalmente desreferenciava, por así falar, ou ir a un enderezo que non é
en realidade, un enderezo lexítimo, cousas malas suceden.
>> E iso é o que pasou pensar Binky.
Entón, lembrar que a historia de que Nick era dicindo aquí foi a mesma idea que o
Eu deseño coa ilusión giz no cadro alí.
X e Y son declarados.
>> Logo asignado ao tamaño dos un int e almacenado en x.
A continuación, a seguinte liña que fixemos * x.
Esta foi a vara máxica de Nick de dereferencing.
Que puxo 42 na memoria apuntado por x.
>> Pero este é o lugar onde as cousas deu terrible mal.
Non?
Tratamos desreferenciava y.
Pero y tiña un valor falso, non?
>> Que a frecha no ángulo inferior esquerdo canto, non é
en realidade, a apuntar cara algo.
É unha especie de facer o que eu fixen aquí no consello.
Entón, as cousas malas suceden, a segmentación fallo ou avaría chupete, neste caso.
>> Pero se, a continuación, corrixir isto, facendo x fica y como é que o cambio de historia?
Ben, se eu fai x recibe y, que é efectivamente o mesmo que dicir
o que é iso, Ox-algo será o mesmo aquí,
Ox-algo.
Ou pictoricamente imos debuxar unha frecha.
>> Entón, aquí en placa con Binky, coa seguinte liña de
código, * y significa ir ata alí.
Onde é que hai?
Significa aquí.
>> E cando nós actualizamos que ser 13 que implica só indo e
13 escribir aquí agora.
Por iso, é posible que non totalmente simple a primeira vista.
Pero para recapitular e utilizar a mesma xerga que Binky estaba usando aquí, entón
os dous primeiros reservar os punteiros, x e y, pero non os pointees.
E pointees non fai xeralmente utilizado prazo.
Pero é absolutamente punteiro.
Pero é o que está a ser apuntado no da nomenclatura de Binky.
>> Esta liña seguinte, claro, aloca un pointee int.
Así, unha peza de memoria - como atraeu máis en o lado dereito alí - e un conxunto
x igual a apuntar cara a el.
Este desreferencia x para almacenar 42 en a memoria que está a apuntar.
E despois diso, está claro, era unha cousa mala.
Porque y non estaba apuntando en nada aínda.
Isto resolve o problema.
Polo tanto, este aínda é o programa de buggy.
Só porque estamos golpe a través do código liña por liña e dicir: oh ben,
deixar caer alí.
Iso é unha cousa mala.
As probabilidades son que o programa só vai deter por completo a esta liña.
Pero se fose para eliminar o accidente de liña e substituílo con os dous últimos
liñas alí atribúe -
coa asignación de punteiro - y para ligar a x como punto de t.
E entón desreferenciava y dun xeito moi segura.
>> Entón onde é que isto nos deixa?
Pois ben, resulta que debaixo do capó na biblioteca CS50, os punteiros son
utilizado ao longo.
E nós imos realmente comezar a pelar de volta a capa antes de tempo.
Pero acontece tamén, unha expresión que algúns de vostedes poden estar familiarizado con,
particularmente aqueles máis cómodo, que é en realidade dunha moi popular
web, ou estourido de pila, nos días de hoxe.
>> Pero iso realmente non ten moito significado técnico.
Sabemos agora que a pila é.
É como unha pila de bandexas dentro dunha comedor.
>> Ou dentro do seu ordenador de memoria its os cadros
que son utilizados por funcións.
Pois ben, resulta que por causa diso moi sinxelo implementación
memoria e dos cadros na chamada apilar, pode realmente asumir o control
dun sistema informático con bastante facilidade.
Pode invadir un sistema, se a xente como non escribimos o noso código
particularmente ben.
>> Se persoas como usamos anacos de memoria ou usar matrices -
aínda máis comunmente -
pero ás veces se esqueza comprobar a límites de nosa matriz como pode
ten-se, por veces, e reiterou moi lonxe tras o final dun array.
No mellor dos casos, o seu programa só podería fallar.
Fallo de segmento, tipo constrangedor.
Non é gran, pero non é necesariamente algo moi malo.
>> Pero se o seu programa é realmente a verdadeira ordenadores dos usuarios, se funciona
nun sitio que a xente aleatorias reais en Internet están batendo, deixando
persoas inducir cousas malas no seu código é xeralmente non é unha cousa boa, porque
isto supón unha oportunidade para tomar o control do computador.
E iso se ve algo enigmática.
Pero eu penso que eu ía asustalos lo con Neste último exemplo aquí.
>> Aquí está un exemplo de código.
E hai unha boa Wikipedia artigo que percorre
isto con máis detalle.
Teño principal no chamado fondo foo, pasando argv de 1.
E iso é só para que poida executar o programa e pasar
unha entrada arbitraria.
>> E entón foo é declarado enriba como aceptar unha cadea, ou máis
precisamente, un char *.
A continuación, el declara unha matriz de caracteres.
Chamalo de un buffer, de xeito máis xeral, de tamaño 12.
Entón, 12 caracteres pode caber dentro deste array chamado c.
>> E entón el usa esta nova función, que é novo, pero non é difícil
entender, copia de memoria.
El copia a memoria do bar, que era pasado variable n, calquera que sexa o
usuario escribiu nunha argv en c.
Cantos bytes?
A lonxitude da corda de bar.
>> Polo tanto, noutras palabras, se o usuario escribe en h-e-l-l-o Intro, a lonxitude da corda
Ola é de cinco anos.
Entón, cinco deses bytes se ve copiado ao array chamado C, que
é de tamaño 12.
Pero o que o usuario escribe nun tempo moito máis palabra que é de 13 caracteres ou 14
caracteres ou 100 carácteres ou máis?
>> Onde se están indo?
Ben, ese cadro, que a bandexa na pila de comedor,
eles están indo para alí.
E iso só vai comezar a substituír outras cousas que xa está
nesa pila, rebordando do conxunto, por así dicir.
>> Entón, pictoricamente, pense nisto deste xeito.
Esta é só unha versión en cor de a imaxe que estamos deseñando.
Na parte inferior, por exemplo, é o principal.
E na parte superior, o que está a ver agora é o cadro, codificados por cores agora, por unha
función chamada foo.
Pero o que é interesante aquí sobre foo é que aquí é o seu cadro.
Entón, el está deseñado como eu fixo, pero en azul claro.
E agora este é o lugar onde c soporte 0 vai.
E é aí onde c soporte 11 vai acabar.
>> Noutras palabras, isto ocorre ser representado como un cadrado.
Pero se só manter estatelando bytes abaixo - ou caracteres - van acabar
na posición 0 todo o camiño ata o 11 por que é 0 indexado.
>> Pero onde está o carácter 13 vai acabar?
Cadê o 14?
Onde está o carácter 50 vai acabar?
>> El seguirá a descender.
Porque aínda que teña deseñado o imaxe coa pila crecendo, o
enderezos, verifícase, ir de pequenas enderezos, pequenas
punteiros, para grandes enderezos.
Entón, simplemente continúa indo a arriba e cara arriba.
>> Polo tanto, se o usuario escribe en Ola, iso é gran.
O erro, non hai problema, seguro de todos.
Pero se o usuario escribe en que imos chamar o código do contraditorio, representado
xenericamente como, ataque, ataque, ataque, ataque, o que pode ocorrer?
>> Agora ben, se toda a entrada que o usuario ingresaran non é só un amigable
ou cadea ofensiva de caracteres.
É, en realidade, unha secuencia de carácteres que se compilou,
realmente é un código.
Quizais sexa o código que exclúe toda arquivos no seu disco duro ou envía spam
ou algo así.
Teña en conta que o que é importante aquí é que O bandido tivo sorte o suficiente para
substituír o anaco vermello de memoria -
que eu non deseñei na miña imaxe, pero esta foto Wikipedia aquí ten -
seu chamado enderezo de retorno.
>> Cando regresa de alimentos, cando retorna de intercambio, Como o ordenador sabe que ir de
aquí enriba até aquí abaixo?
Ou no segmento de tecnoloxía enriba, como el sabe que van desde o intercambio de
código - o 0 e 1 do que compoñen intercambio -
de volta ao inicio?
Hai un chamado enderezo de retorno almacenado no mesmo cadro de pila, en
mesma bandexa cafetería.
>> Entón, se o bandido é intelixente dabondo para poñer un código de ataque, un código de ataque, ataque
código, e ter sorte o suficiente -
moitas veces a través de intento e erro - a sobrescribir o enderezo de retorno vermello,
co enderezo eo aviso arriba.
Observe 0835C080.
Está escrito atrás encima razóns que imos quizais revisitar.
Este número é o que.
>> Entón, se o bandido ten sorte o suficiente ou é intelixente o suficiente para substituír o vermello
tira de memoria co enderezo de código que el ou ela ten de algunha maneira
inxectado no seu computador, penso que quen código será devolto
así foo está feito de execución?
>> Código do bandido.
Polo tanto, este código de ataque, AAA, unha vez máis, poder enviar spam, pode borrar todos os ficheiros
no seu disco duro.
Pero iso é o que realmente un estourido de pila é, ou un estourido de buffer, ou un
ataque de estourido de buffer.
>> E é incrible, incrible común para este día cos programas escritos en
C, C + +, e mesmo algunhas outras linguas.
Na mesma nota asustado, imos termina cunha broma.
>> [Risas]
>> Vexo vostede na Mércores.
Na seguinte CS50 -
Entón, eu estou fóra de lámpadas disco hoxe, pero esperar, libre de graxa do leite, a metade do teléfono
libro, o zume de laranxa que eu bebín hoxe.
Cable USB, unha chave inglesa.
>> [Música tocando]