[MÚSICA DE XOGO]
>> DAVID J. Malan: Todo ben.
Este é CS50.
E este é o inicio da semana 5.
E como ten que notar, parte do material
está quedando un pouco máis complexo, a pouco máis denso.
>> E é moi doado, sobre todo se foi o costume hai algún tempo,
estar tentando rabiscar máis todo o que facemos, nós estamos dicindo na aula.
Pero entender, que quizais non sexa o enfoque pedagóxico ideal
para aprender este tipo de material, e material dun xeito máis xeral.
E así temos o pracer de anunciar propia Gheng dese CS50
Gong comezou a prepararse un conxunto canónico de notas
para o curso, a esperanza da que é o que, unha, estes
non só servir como un referencia e un recurso
para material de revisión e vai de volta a través do material que pode ter
escapouse a primeira vez, pero tamén para que as súas cabezas poden ser máis
-se que abaixo, cando chega o momento de charla,
de modo que pode se involucrar máis pensativo, como
oposición ao máis scribbly.
>> Co que dixen, o que vai atopar en o sitio é documentos como este.
E observen, na esquina superior esquerda, hai non só unha táboa de contidos,
pero tamén códigos de tempo que será inmediatamente ir ti
á parte correspondente no vídeo en liña.
E o que Chang fixo aquí é, esencialmente, documentado
o que pasou neste especial de conferencias.
E moitas das conferencias son Xa están en liña agora con este URL.
E imos seguir a publicar o resto daqueles ata finais desta semana,
por iso aproveitar deste recurso.
>> Así, sen máis delongas, comezamos a pelar
a capa que foi cadea por algún tempo.
E o que dicimos unha cadea en realidade é da semana pasada?
Entón, estrela de char.
E Char estrela, así, o que que iso realmente significa?
Ben, todo este tempo, se nós foi chamada dunha función,
como getString, e almacenamento o retorno chamada
valor de getString nunha variable-- chámase
s tipo string-- que teño escrito a liña de código alí enriba.
E é só cando ver o meu caligrafía grande aquí
eu entender o quão atroz que é iso.
>> Con todo, imos supor que, no lado da man dereita
é, con todo, unha razoable representación do que é
vén a suceder todo isto tempo con getString.
getString, claro, fica un cadea.
Pero o que iso realmente significa?
Isto significa que queda un anaco de memoria do sistema operativo
chamando unha función, chamada malloc.
Pero máis sobre iso máis tarde.
E entón el enche que pedazo de memoria
coas letras que o usuario ten escriba, seguido, por suposto,
un carácter nulo, ou barra invertida cero ao final.
>> Mentres tanto, no lado esquerdo desta historia, todo ese tempo,
vimos declarar unha variable, como s.
E esa variable é o que agora comezará a chamar un punteiro.
Non é unha caixa dentro da cal poñemos a corda, Daven, por si só,
pero poñemos naquela praza caixa á esquerda o que exactamente?
Si?
>> Audiencia: O enderezo de onde está situado na memoria.
>> DAVID J. Malan: Exactamente.
O enderezo de onde Daven está situado na memoria.
E non onde todos Daven está situado, de por si, pero especialmente a dirección
de que?
Si?
>> Audiencia: Primeiro personaxe.
>> DAVID J. Malan: O primeiro carácter en Daven, que, neste caso,
I proposto foi arbitrariamente e irrealisticamente 1, OX 1,
o que significa só o número hexadecimal de 1.
Pero seguramente para ser un número moi grande
que poderiamos chamar cun 0x como un prefixo,
representando un personaxe hexadecimal.
E por que non necesitamos saber onde o resto dos personaxes de Daven
son, por mor do que deseño simple decisión que foi tomada hai moitos anos?
Si?
>> Audiencia: Barra invertida 0.
DAVID J. Malan: Si, exactamente.
A barra invertida 0 permítelle, aínda que de tempo lineal, para atravesar a corda,
a pé de esquerda a dereita, cun loop, ou un tempo
loop, ou algo parecido que, e determinar, oh, aquí
é o final desa secuencia particular.
Así, con só a dirección en o inicio dunha cadea,
podemos acceder a totalidade de Porque todo este tempo,
unha secuencia foi só unha estrela de char.
>> Por iso, é certamente ben para seguir a utilizar a biblioteca CS50 e esa abstracción,
por así dicir, pero imos comezar a ver exactamente
o que está pasando debaixo de todo este tempo.
Entón pode lembrar este exemplo, tamén, a partir da última vez, comparar 0,
que non chegou a comparar.
Pero comezamos a resolver iso.
>> Pero como, se cadra, unha reciclaxe, Podería interesar a alguén
nun elefante rosa de hoxe, tamén feita por Chang?
Que tal ti diante? [Inaudível].
Imos cara arriba.
>> E nese medio tempo, como veña, imos
considerar por un momento o que este código foi realmente facendo.
É declarar dúas variables se top, s e t, e chamando getString.
Este non é un programa de fácil utilización, porque non lle di o que facer.
Pero imos supoñer que estamos focando a parte suculenta.
E entón, o que facemos, se s é igual a é igual a t, debe dicir printf,
inseriu o mesmo.
Ola.
Cal é o seu nome?
>> Janelle: Janelle.
DAVID J. Malan: Janelle, pracer de coñece-lo.
Polo tanto, o seu reto no man a este elefante
é o primeiro en chamar-nos un retrato do que está sendo representados neses dous primeiros
liñas.
Así, s e t pode ser representado como na pantalla?
E pode só deseña-lo con dedo na pantalla grande.
>> Polo tanto, hai dúas metades para cada lado da ecuación.
Polo tanto, non hai s á esquerda, e entón GetString á dereita.
E despois hai t á esquerda, e, a continuación, GetString á dereita.
Entón, como podemos comezar facer un deseño que
representa o que está a suceder aquí na memoria, diría?
E déixeme deixar explicar o que está facendo que vaia.
>> Janelle: Aceptar.
Ben, en primeiro lugar, el estaría pedindo vostede para obter a secuencia de entrada.
E sería store-- oh, sinto moito.
DAVID J. Malan: Aceptar.
Boa.
E iso chámase que?
Oh, Aceptar.
Continúe.
Eu non quería interromper.
Janelle: Sentímolo.
Por iso, sería introducir-lo en a dirección non de-- seguro.
Non me lembro exactamente o número, pero eu creo que foi a partir de 0.
>> DAVID J. Malan: Está todo ben, porque eu fixen os números anteriores,
polo que non hai resposta correcta.
>> Janelle: Comezando a 0 arco.
>> DAVID J. Malan: OK, entón o elemento 0.
Claro.
>> Janelle: E entón foise como só un dous-letter--
>> DAVID J. Malan: OK, de volta para ti.
>> Janelle: Entón o elemento 0, e logo, un elemento ou elemento 2.
DAVID J. Malan: E que parte do a imaxe que está deseñando agora?
A chamada a getString?
Ou a declaración de s?
>> Janelle: A declaración de s, eu creo.
Oh, o getString porque sería ser introducido en cada un [? área. ?]
>> DAVID J. Malan: Good.
Exactamente.
Aínda que isto efectivamente retorna un array, recall,
cando volvemos unha cadea, podemos índice para esta cadea utilizando 01 e 2.
Tecnicamente, estes son, probablemente, representado por enderezos individuais,
pero iso é bo.
>> Entón supoño que, se eu poida só rápido encamiñar a onde paramos
última vez que, se un de as cordas era g ab e,
barra invertida 0, representando así Gabe entrada, como podemos representar s agora?
Se esta é a memoria que está foron devoltos por getString?
>> Janelle: Sería representado por un arco?
>> DAVID J. Malan: por un arco?
Ben, non.
Nós só dicir que, pictoricamente, déixeme ir adiante
e propoñer que, se isto é s, esta é o valor de retorno de getString.
E deseñou iso como 0, 1, 2, que é perfectamente razoable, porque
pode indexar na secuencia, como tal.
Pero só para ser consistente co última vez, deixe-me ir adiante
e arbitrariamente propoñer que esta é a dirección 1, este é o enderezo 2,
este é o enderezo 3, e así por diante.
E así, só para ser super por suposto, o que está a suceder
ir ao s como un resultado que primeira liña de código, diría?
>> Janelle: Enderezo 1?
>> DAVID J. Malan: Exactamente.
Así, abordar 0x1.
E mentres tanto, deixe-me ir adiante e duplicar moito do que fixo
e engadir o meu propio t aquí.
Se eu fose para escribir Gabe de novo, por segunda vez,
cando proceda con getString, onde, por suposto, é Gabe vai?
Ben, presumably--
>> Janelle: Como aquí?
DAVID J. Malan: Yeah.
Janelle: Ou tamén nas mesmas caixas?
DAVID J. Malan: Déixeme propoñer, si, exactamente, polo que nestas caixas adicionais.
Pero o que é fundamental, agora, é que, mesmo aínda que eu deseñei estas moi preto
together-- 0x1, este é 0x2-- en realidade,
iso agora pode ser o enderezo 0x10, por exemplo, e de 0x11, 0x12 e,
e así por diante.
E así, se ese é o caso, o que vai acabar por aquí en t?
>> Janelle: 0x10?
DAVID J. Malan: Exactamente.
Entón 0x10.
E agora, a pregunta final.
Ten, de lonxe, tiña que traballar a máis difícil para un elefante ata o momento.
Ata agora, se eu puxar arriba o código unha vez máis, cando fago, na liña de tres,
se s é igual a igual t, o que eu son, en realidade, comparando que temos deseñado aquí?
>> Janelle: Os dous enderezos?
DAVID J. Malan: Exactamente.
Entón, eu estou dicindo é S igual xeito at?
Noutras palabras, é un xeito igual a 10?
E, por suposto, o resposta obvia é agora, non.
E así, este programa é, en definitiva vai imprimir o que, diría?
>> Janelle: Sería, inseriu o mesmo?
>> DAVID J. Malan: Entón, se s representa 1 e t é 10?
>> Janelle: Escribiu cousas distintas.
>> DAVID J. Malan: Exactamente.
Inseriu cousas distintas.
Todo correcto.
Entón, unha salva de palmas, se puidésemos, aquí.
[Aplausos]
Iso foi doloroso.
Sei.
Moi ben feito.
Entón agora imos ver se non podemos desmembrar o que a corrección era.
E, por suposto, cando se fixa isso-- que agora vai representar en green--
fixemos algunhas melloras aquí.
En primeiro lugar, así como unha sanidade comprobar, estou comprobando primeiro
se s é igual a nulo e t é igual a null.
E só para quedar claro, cando pode s ou t ser nulo no código coma este?
Cando S ou T pode ser nulo.
Si?
>> Audiencia: [inaudível].
>> DAVID J. Malan: Exactamente.
Se a secuencia de caracteres que o usuario ingresaran é un camiño moi longo
para caber na memoria, ou algún caso canto estraño así,
getString, como veremos, literalmente hoxe, na súa documentación,
di que vai voltar nulo como un valor de sentinela especial,
ou só unha especie de símbolo especial isto significa que algo deu errado.
Por iso, queremos comprobar a que, xa que verifica-se
que nulo é un valor moi perigoso.
>> Moitas veces, se tentar facer algo con nulo inclúen un function-- pasalo
como entrada, para que a función instance-- pode moi vai bater e, con el,
derrubar todo o seu programa.
Polo tanto, esta terceira liña agora é só unha sanidade cheque, comprobación de erros, se quere.
Isto é un bo costume agora para nos para entrar en calquera momento que
proba a usar un valor que podería, potencialmente, ser nulo.
>> Agora, na cuarta liña aquí, "Se strcmp (s, t)," ben,
que é o que se refire?
Ben, dixo que esta era unha forma moi sucinta función chamada a comparación de cadeas.
E o seu propósito na vida é comparar seu primeiro argumento contra ela en segundo lugar,
pero non en termos de seus enderezos, como fixemos involuntariamente un momento
atrás co código vermello, pero no canto de comparar os dous
cordas no humanamente intuitiva forma, comparando este, contra este,
contra iso, contra iso, e logo deixar que e cando un
ou ambos os dedos alcanza unha barra invertida 0.
Strcmp Entón anos alguén aplicado aplicar a nós a función
que esperabamos, teriamos conseguido por só dous valores de comparación simple.
>> Agora, francamente, eu sigo deseño todos estes varios números.
Pero a realidade é, eu estiven converténdose os para arriba todo o tempo.
E entón déixeme ir adiante e rabiscar estes para fóra
facer un punto en que, ao final do día e seguir adiante,
nós non estamos indo realmente se preocupan que aborda as cousas son, en realidade,
na memoria.
Entón eu non vou deseñar estes tipos de números moito máis,
Eu son só un resumo este fóra un pouco máis agradable con só frechas.
>> Noutras palabras, se s é un punteiro, Ben, imos só deseña-lo literalmente
como un punteiro, unha frecha apuntando cara de si mesmo para outra cousa,
e non se preocupe máis sobre as minúcias destes enderezos
que, unha vez máis, eu fixen de calquera maneira.
Pero imos ver os enderezos, ás veces, cando a depuración do código.
>> Agora, con todo, este programa aquí correccións, por suposto,
problema que comparando estas dúas cordas.
Pero nós funcionamos noutro problema.
Esta foi a partir da copia programar última vez,
segundo o cal, eu estaba tentando capitalizar só o primeiro carácter nunha cadea.
Pero o que era o síntoma vimos a última vez, cando
un usuario inseriu un valor, como Gabe en minúsculas, para s,
entón atribuído s en t, tal como na terceira liña non,
e entón eu tente capitalizar t soporte 0?
Cal foi o efecto de cambiando t soporte 0 aquí?
>> Audiencia: Mudouse s.
>> DAVID J. Malan: Si, Mudei s, tamén.
Porque o que realmente estaba a suceder?
Ben, deixe-me ver se eu podo borrar esta imaxe, como segue.
>> Se s sexa, outra vez, a palabra g, A, B, E, barra invertida, 0 e s
imos seguir a deseñar como unha caixa aquí, pero non máis enderezos.
Imos deixar de facer as cousas.
Nós só facer un debuxo para simplificar o mundo.
>> Cando declaro t con corda t, que crea ese anaco de memoria.
Praza pasa a ser 32 bits na maioría dos ordenadores.
De feito, se xa escoitou falar dun ordenador cunha arquitectura de 32 bits,
moi chique-dicir, que só significa que usa enderezos de 32 bits.
E como un técnico de banda, Se xa se preguntas
Por que os ordenadores máis antigos, se o intentou sopa-los con moita memoria RAM,
só pode ter un máximo de catro gigabytes de memoria RAM,
ben iso é porque, literalmente, ordenador antigo só podía
Cantidade de tan elevada como 4 millóns, 4 millóns de bytes,
porque se utilizando 32 bits números de enderezos.
>> Pero en calquera caso, neste exemplo, da historia moito máis simple.
t é só outro punteiro, ou realmente unha estrela char, aka cadea.
E como me gustaría actualizar esta foto agora con esta segunda liña de código,
despois do punto, punto, punto?
Cando fago corda t é igual a s punto e coma, como é que esta foto cambiar?
Si?
>> Audiencia: [inaudível].
>> DAVID J. Malan: Yeah.
Exactamente.
Acaba de poñer unha frecha t caixa para o mesmo enderezo,
a mesma primeira letra deu.
Ou tecnicamente, se esta cara aínda estaba en 0x1,
é coma se tivese Aquí 0x1 e 0x1 aquí.
Pero, de novo, quen lle importa sobre os enderezos?
É só a idea de que agora importa.
Entón é iso que está pasando aquí.
Entón, por suposto, se fai soporte t 0, que é a reserva de matriz,
de course-- e, a verdade, parece como se houbese unha matriz por aquí,
pero agora hai unha cousa estraña.
Saber que a linguaxe de programación, C, ofrece este recurso,
polo que, aínda que t é un punteiro, é s é un punteiro,
tamén se pode usar aquel familiar, corchete cómodo
notación para ir ao primeiro elemento, ou o segundo elemento, ou calquera elemento
que ese punteiro está apuntando para por, presuntamente, el
é, como no caso presente, apuntando algunha matriz.
>> Entón, como imos solucionar isto?
Francamente, isto é onde ten un pouco esmagadora a primeira vista.
Pero aquí é unha versión nova e mellorada.
>> Entón, primeiro, eu estou quedando librar da biblioteca CS50,
só para expoñer que s é de feito unha estrela char, só un sinónimo.
E t é tamén unha estrela de char.
Pero o que está pasando no do lado dereito da liña
onde t é asignado un valor?
>> Que é malloc?
Que é strlen?
Que é sizeof (char)?
Por que diaños fai iso ollar liña tan complexo?
O que está facendo en un alto nivel?
Que o almacenamento en t?
Si?
Audiencia: É a concesión dunha certa cantidade de espazo de memoria.
É para gardar, creo, letras [inaudível].
>> DAVID J. Malan: Perfecto.
Perfecto.
É atribución dun certo cantidade de espazo de memoria
para almacenar, presuntamente, cartas futuras.
E, en particular, malloc polo tanto, está retornando dunha cousa?
>> Audiencia: Alumnado o [inaudível]?
DAVID J. Malan: Exactamente.
Retornando a dirección de que a memoria, que é un xeito elegante de dicir,
retorna a dirección do primeiro byte desta memoria.
A responsabilidade recae sobre min para recordar a cantidade de memoria que realmente
asignado ou malloc pediu.
>> Agora que é isto?
Ben, aínda que non haxa un lote de parénteses aquí,
malloc leva só un único argumento.
E eu estou especificando strlen de s, para dar me como moitos bytes, como existen en s,
pero engade un.
Por que?
Si?
>> Audiencia: A barra invertida 0.
DAVID J. Malan: Exactamente.
Temos que facer un pouco de limpeza.
Entón, por que non hai unha barra invertida 0, o mellor é lembrar diso.
Se non, nós imos para crear unha cadea que
Non ten que terminador especial.
>> Mentres tanto, só para ser super anal, teño sizeof (char),
só no caso de alguén corre o meu código non no aparello CS50,
pero quizais un ordenador diferente en total, onde chars
é un byte, por convención, pero dous bytes, ou algo máis que iso.
É só para ser super, Super aversión a erros.
Aínda que, en realidade, é probablemente será un 1.
>> Agora, mentres tanto, eu vou adiante e copiar o corda, soporte t i é igual a pista t s.
E eu vou retrasar a última semana código fonte para ver o que está pasando.
Pero o principal argumento, eo razón de eu poñer o código agora en verde,
é porque esa última liña, t soporte 0 é igual a toupper,
ten o efecto de capitalizar que secuencia?
t e / ou s?
Esta última liña de código.
>> Só t, porque o que é pasou esta vez,
se eu lixeiramente desfacer o último paso, Que pasou é, cando eu chamo malloc,
Eu esencialmente obter un anaco de memoria que é do mesmo tamaño que o inicio,
porque esa é a aritmética que eu fixen.
Estou almacenando en t enderezo dese anaco de memoria.
Aínda que isto parece bo e bonito, agradable e en branco,
A realidade é que é, o que imos seguen chamando, os valores de lixo aquí.
Este anaco de memoria pode moi moi ben ser usado antes,
uns segundos, algúns minutos.
Polo tanto, non podería absolutamente ser números ou letras alí, só por casualidade.
Pero eles non son válidos, ata que eu me cubrir este anaco de memoria
con caracteres reais, como eu facer ese loop for alí.
Todo non?
>> Entón, agora, o clímax da Estes tres exemplos
que foron aparentemente dobres última vez, Neste exemplo intercambio, esta función
traballou no sentido que trocou a e b.
Pero non deu correcto en que outro sentido?
Si?
>> Audiencia: [inaudível].
>> DAVID J. Malan: Exactamente.
Se eu fose para chamar esta función de another-- por exemplo,
desde unha función como principal, onde Eu teño unha variable, x e y, como eu
fixo a semana pasada, o mesmo código, e eu pasar en x e y
Cambiar e despois chamar Swap-- tanto, por suposto, é a versión correcta
é o que estamos a piques de ver-- non funcionou.
Entón, cal é a corrección?
>> Ben, entón, pode ser suposto, deixe-me ir adiante
e-- me dar un segundo aquí, e ver se podo amosar-lle a última, que
será em-- imos ver se podo atopar esta OK fast-- real, [inaudível].
OK, está alí.
Así, ignorar as ordes que estou só escribindo.
Quero que recuperar a o último minuto dun exemplo
desde a última vez, que agora chámase non cambiar.
>> Polo tanto, non Intercambio é onde paramos a última vez,
polo cal, I inicializar x e y de un a dous.
Eu, entón, chamar de Intercambio, pasando en 1 e 2.
E entón esta función traballou nalgún sentido,
pero non tiña permanente efecto xe y.
Entón, a cuestión en apreciado é, como agora é que imos realmente resolver este problema?
Cal é a solución na man?
>> Ben, en swap.c, que é novo hoxe, notar algunhas diferenzas.
x e y son o mesmo.
Pero o que é claramente diferente sobre liña 25?
O que hai de novo alí, se se lembra o que parecía un segundo atrás?
>> Audiencia: [inaudível].
>> DAVID J. Malan: Yeah.
Así, os ampersands son unha nova peza de sintaxe, non só neste programa,
pero tamén en termos máis xerais en CS50.
Ata o momento, eu non creo que temos coñecemento de exemplos
ou realmente falado sobre eles en calquera detalle, agás, quizais, cautelarmente
en corte, un e comercial como esta.
Ben, acontece que é un comercial dos últimos anacos de nova sintaxe
imos aprender.
Todo isto significa é o dirección dalgunha variable.
En que dirección se x vivir?
Pero a dirección que y vivir?
Porque se o problema fundamental antes
foi que xe y eran trasladados como copias, o que realmente queremos facer
é proporcionar Intercambio con como un tesouro mapa que leva a que x e y efectivamente
están na memoria RAM, para que Cambiar pode seguir este mapa
e ir onde queira que x ou y marca o local e cambiar os valores reais 1 e 2
alí.
>> Entón cambiar que cambiar un pouco tamén.
E, a primeira vista, isto pode parece un pouco semellante ao carbón estrela.
E de feito é.
Así, un é un punteiro para o tipo de datos, derivada porción destacada?
Polo tanto, é un int.
>> Así, un non é un int, é a dirección dun int.
E do mesmo xeito, b agora vai para ser o enderezo dun int.
Entón, cando eu agora chamo de intercambio de Main, Eu non vou dar Cambiar 1 e 2.
Vou dar-lle como Ox-algo e Ox-algo,
dous enderezos que levarán Cambiar para os seus lugares reais
na memoria do meu ordenador.
>> Entón, agora, a miña aplicación resto que cambiar un pouco.
O que é, obviamente, diferente agora nestas tres liñas de código?
Hai esas estrelas malditos todos sobre o lugar, non?
Entón, o que está pasando aquí?
Si?
>> Audiencia: É evidentemente [inaudível].
>> DAVID J. Malan: Exactamente.
Polo tanto, neste context-- e iso non era a mellor decisión de proxecto, de feito,
anos.
Neste contexto, no que só ten unha estrela,
e non ten un tipo de datos, como int, inmediatamente á esquerda,
en vez diso ten un signo igual, de forma clara, Neste contexto, cando di que protagonizar un,
isto significa ir á dirección que está nun.
Segue o mapa do tesouro, por así dicir.
>> E mentres tanto, na liña 37, isto significa o mesmo.
Ir ao enderezo dun, e poñer o que hai?
Sexa cal sexa a local que b especifica.
Noutras palabras, ir b.
Obter este valor.
Vaia a unha e, por igual asinar, o operador de asignación,
poñer este valor alí.
>> Do mesmo xeito, int temperatura é só un int.
Nada que cambiar en Temp.
É só un vaso de reposición de Annenberg un pouco de leite ou zume de laranxa.
Pero eu teño que dicir, ir b.
Vaia a este destino e poñer o valor en temperatura alí.
Entón, o que está a suceder, entón?
Cando realmente chamar Intercambia este tempo, se esta primeira bandexa aquí representa principal,
Nesta segunda bandexa representa intercambio, cando Eu paso Ampersand xe y comercial
de principal de cambiar, só para quedar claro, o que é ese cadro de pila de recepción?
Si?
>> Audiencia: [inaudível].
DAVID J. Malan: Exactamente.
O enderezo de xe a dirección de Y.
E pode pensar neles como enderezos postais.
33 Oxford Street e 35 Oxford Street, e
quere mover os dous edificios que están nesas localizacións.
>> É unha especie de unha idea ridícula, pero iso é todo o que queremos dicir por enderezo.
Onde o mundo pode atopa estes dous enteiros?
Onde o mundo se pode atopar os dous edificios?
Entón, finalmente, despois de todo este tempo eu entrar código fonte e compilar de hoxe
Cambiar e executar ./swap finalmente ao primeira vez que realmente vemos que
meus valores teñen, de feito foi trocado correctamente.
E agora, podemos ata ter coñecemento do presente, digamos, gdb.
>> Entón deixe-me ir ao mesmo ficheiro.
Deixe-me ir adiante e executar gdb de ./swap.
E agora, en cambiar, eu estou indo a ir adiante e establecer un punto de ruptura na principal.
E agora eu estou indo a ir adiante e executar o programa.
E agora imos ver o meu código parou en liña.
>> Se eu ir adiante e impresión x, o que debo ver aquí?
É unha pregunta.
Diga de novo?
>> Audiencia: [inaudível].
>> DAVID J. Malan: Entón números aleatorios, quizais.
Poida que eu teña sorte, e é agradable e simples, como 0.
Pero é posible que algún número aleatorio.
Neste caso, eu tiven sorte.
El só pasa a ser 0.
Pero é realmente sorte, por que non ata que eu
tipo seguinte e, a continuación, imprimir x ten que liña de código, liña 19, foron executados.
>> Mentres tanto, se eu escribir próxima vez, e agora imprimir y, eu vou ver 2.
Agora, se eu escribir a continuación, que vai estar un pouco confuso, porque agora,
o printf aparecerá a pantalla, como o fixo. x é 1.
>> Imos facer iso de novo.
E agora, aquí é onde as cousas comezan a estar interesantes.
Antes de me chamar de Intercambio ou mesmo paso para el, imos dar un olhadinha.
x é, de novo, 1.
Y é, por suposto, sanidade rápido comprobar, 2, polo que non é difícil alí.
Pero o que é comercial x?
Resposta, é unha especie de vista funky.
Pero a estrela int en parénteses é só forma de PIB de dicir isto é unha dirección.
Non é un int, que é un punteiro para un int, ou doutro xeito coñecido como un enderezo.
>> Que é esa cousa tola?
Nunca vimos algo ben así antes.
Polo tanto, este é o enderezo no meu ordenador de memoria de onde x pasa a vivir.
É Ox-algo.
E este é, francamente, por que Eu comecei a deseñar frechas,
no canto de números, porque quen realmente lle importa
Cal é o int nun determinado enderezo que é tan grande.
Pero bffff0c4, todos estes son en realidade díxitos hexadecimais,
que van de 0 a f.
>> Entón, nós non imos vivir moi tempo en que estas cousas son.
Pero se eu imprimir y, claro, vexo 2.
Pero comercial y, vexo esta dirección.
E aviso, para os curiosos, Cara a unha distancia entre x e y?
Pode ignorar a maior parte do enderezo.
Catro bytes.
E iso é consistente coa nosa anteriormente afirman que o tamaño é un int?
Catro bytes.
Polo tanto, parece que todo está aliñados ben, como podería esperar, na memoria.
>> Entón, agora, imos avanzar rapidamente ao final desta historia.
Imos adiante e escriba paso, para mergullo na Función Intercambio.
Agora conta, se eu escribir un, é mesmo que o enderezo de x.
Se eu escribir b, é idéntica ao enderezo de y.
Entón, o que eu debería ver se eu dicir, ir ao enderezo dun?
Así imprimir protagonizar un.
Así estrela significa ir alí, neste contexto.
Ampersand significa que é o enderezo.
Así, unha forma protagonizar 1.
E estrela de impresión b dáme 2.
>> E déixeme asumir, para o momento, que polo menos o código que
seguirá a executar pode ser agora fundamentado a través desta forma.
Pero imos voltar a esta idea en pouco tempo.
Polo tanto, esta versión do intercambio é agora correcta e permite
nos para cambiar este tipo de datos particular.
>> Así, todas as preguntas, entón en Cambiar?
En estrela?
O enderezo?
E vai ver, con conxunto de problemas 4, dalgún xeito,
pero o problema axuste 5, en definitiva, o xeito no que estes as cousas son útiles e obter máis
cómodo con eles, como un resultado.
Calquera cousa?
Todo correcto.
Entón malloc é, de novo, esta función que aloca memoria, a memoria
distribución.
E por que iso é útil?
Ben, todo este tempo, vostede está a usar malloc.
Se considerar agora como GetString obras, presuntamente, é
foi pedir a alguén por unha peza de memoria, en calquera momento o usuario escribe unha cadea
no, porque seguramente non sabía, como persoal CS50,
como aquelas cordas grande que o ser humano están indo escribir podería ser.
>> Entón, imos, por primeira vez, comezar a Descasque todas como funciona a biblioteca CS50,
por medio dun par de exemplos que nos levará alí.
Entón, se eu abrir gedit e abrir scanf 0,
imos ver o seguinte código.
Scanf 0, dispoñible na páxina web para hoxe, ten relativamente poucas liñas de código
aquí, 14 a 20.
E imos ver o que está facendo.
El declara un int, chamado x.
Di algo así como, número por favor.
E agora di, scanf% i, e x.
Polo tanto, hai unha morea de cousas novas alí.
>> Pero scanf, pode tipo de pensar como o contrario de printf.
printf, por suposto, para a impresión en pantalla.
tipo scanf de scans de usuario do teclado algo que el ou ela teña ingresaran.
>> % I é como printf.
Isto quere dicir que a espera usuario introduza un int.
E agora, por que pensas que eu pode estar pasando scanf & x?
Se o obxectivo de vida de scanf é facer que algo do usuario,
cal é o significado pasando-o, e x, agora?
Si?
>> Audiencia: [inaudível].
DAVID J. Malan: Exactamente.
Todo o que eu, o ser humano, datilografada, miña entrada será gardado no lugar.
Non é suficiente, lembre, só pasar en x, porque a xente xa viu,
calquera momento que pasa só unha variable cru, como un enteiro, de algunha outra función,
Por suposto, isto pode cambiar isto variable, pero non permanentemente.
Non pode ter un efecto sobre Principal.
Ela só pode cambiar a súa propia copia local.
Pero se, no canto diso, non dáme a real int,
pero me dar instrucións para int que, agora, sendo scanf,
Certamente, podo seguir ese abordar e poñer un número non
para que teña acceso a el tamén.
>> Entón, cando eu executar este programa, xa veremos.
Fai scanf 0 punto barra, scanf 0.
E se eu agora escriba un número como 50, grazas ao 50.
Se eu agora escriba un número como 1 negativo, ao negativo 1.
Agora escriba un número como 1,5, hm.
Por que o meu programa me ignorar?
Ben, porque simplemente, eu che dixen que esperar só un int.
Todo correcto.
Así que esta é unha versión deste.
Imos levar as cousas por riba de un entalhe e propoñer que iso non é bo.
E aquí reside un exemplo moi sinxelo de como podemos comezar a escribir código
que outras persoas poidan explorar ou comprometer, facendo cousas malas.
Así, liña 16, tan semellantes en espírito de antes,
pero eu non estou declarándose o int neste momento.
Estou declarándose o carácter estrela, tamén coñecido como corda.
>> Pero o que iso realmente significa?
Entón, se eu non especificar unha address-- e Estou chamando-o de forma arbitraria, buffer,
pero eu podería chamalo é, para ser simple-- e entón eu fago iso, me explique,
se puidese, con base na anterior lóxica, o que está facendo no scanf liña 18,
se pase% s e buffer, cal é o enderezo?
Que é scanf, se aplicar o exactamente a mesma lóxica que a versión 0,
vou tentar facer aquí, cando o usuario escribe algo en?
Si?
>> Audiencia: [inaudível].
>> DAVID J. Malan: Exactamente.
Scanf, pola lóxica anterior, vai levar a cadea
que o ingresaran humano em-- agora é unha cadea,
Non é un número, presuntamente, se el ou ela cooperates--
e vai poñer isto secuencia na memoria en calquera dirección
tapón especifica.
E iso é óptimo, porque o buffer é realmente deseñado para ser un enderezo.
>> Pero eu reivindico este programa é buggy nun forma moi grave, xa que o valor é
tapón por defecto?
O que eu inicializar en?
O anaco de memoria?
Eu non teño, non?
>> Entón, aínda que eu teña asignado un estrela de char que xa non se chama s,
chámase en vez, de xeito buffer-- imos debuxar o nome dunha variable
agora como buffer-- se eu non teño chamado getString ou malloc aquí,
que efectivamente significa que tapón é só un valor de lixo.
>> Agora, o que significa isto?
Isto significa que eu teño dito scanf esperar unha cadea de usuario.
E vostede sabe o que?
O que quere que esta cousa está a apuntar para-- e eu chamar punto de interrogación,
pero, en realidade, que vai ser algo así como OX 1, 2, 3, non?
É un valor falso que só pasa a ser alí de antes.
Entón, dito doutro xeito, é como se tapón é só
apuntando a algo na memoria.
Eu non teño ningunha idea do que.
>> Entón, se eu escribir Gabe agora, vai para tratar de poñer g-a-b-e / 0 non.
Pero quen sabe o que é iso?
E, no pasado, calquera xa que tente reproducir
memoria que non pertence para nós, o que pasou?
Ou case sempre.
Fallo de segmentación, non?
>> Esta frecha, eu non teño ningunha idea de onde é anotador. É só un valor aleatorio.
E, por suposto, se interpretar un valor aleatorio como enderezo,
está indo a ir a algún destino aleatoria.
Entón Gabe pode de feito accidente meu programa, neste caso aquí.
>> Entón o que podemos facer iso é case tan malo?
Considero este terceiro e último exemplo de scanf.
Esta versión é mellor en que sentido?
Se está cómodo co problema anterior, este é mellor.
Por que?
>> Audiencia: [inaudível].
DAVID J. Malan: Good.
Entón, neste caso da liña 16 é mellor, no sentido
que estamos explicitamente a asignación dunha memoria.
Non estamos a usar malloc, Utilizamos a 2 semanas
visión de só declarar unha matriz.
E nós dixemos antes que unha secuencia é só un conxunto de caracteres,
entón iso é totalmente lexítimo.
Pero é, por suposto, como vostede nota, tamaño fixo, 16.
>> Polo tanto, este programa é totalmente seguro, se eu escribir
en secuencias dun personaxe, de dous caracteres cordas, 15 cadeas de caracteres.
Pero así que eu comezar a escribir 16, 17, 18, 1000 cadeas de caracteres,
onde está esa corda vai acabar?
Vai acabar en parte aquí.
Pero, entón, quen sabe o que máis está alén dos límites
desta variedade particular?
>> É como se eu tivese declarou 16 caixas aquí.
Entón en vez de aproveitar todos os 16, imos finxir que eu deseño 16.
Pero se eu tente ler unha cadea que é moito máis longo, como 50 caracteres,
Vou comezar a poñer a, b, c, d, x, y, z.
E esta é presuntamente algún outro segmento de memoria
que, de novo, pode causar meu programa trabe,
por que non pediu nada máis que 16 bytes.
>> Entón, quen lle importa?
Ben, aquí está a biblioteca CS50.
E a maior parte deste é só como instrucións enriba.
A biblioteca CS50, todo este tempo, tivo esta liña na liña 52.
Vimos typedef, ou vai ver typedef
en pset 4, que crea unha sinónimo polo cal carácter estrela pode ser máis
simplemente refire como cadea.
Polo tanto, este é un dos algunhas Rodas pequenas
usamos secretaría debaixo do capó.
>> Mentres tanto, aquí está a función, getchar.
Agora, ao parecer, non hai corpo para el.
E, de feito, se eu continuar desprazamento, realmente non
ver calquera implementacións destas funcións.
Como unha verificación de sanidade, por que isto?
>> Audiencia: [inaudível].
DAVID J. Malan: Yeah.
Polo tanto, este é o ficheiro de cabeceira.
E arquivos de cabeceira conteñen prototipos, ademais dalgunhas outras cousas, ao parecer,
como typedefs.
Pero en CS50.c, que temos nunca lle deu a título definitivo,
pero foi no aparello CS50 todos esta vez, ben no fondo das súas carpetas,
ter en conta que non hai un todo chea de funcións aquí.
>> De feito, imos rodar cara abaixo.
Imos ignorar a maioría deles, polo de agora.
Pero descenda ata getInt para ver como getInt funciona.
Entón aquí está getInt.
E se realmente lle importa como chegar int funciona, aquí é a súa documentación.
E entre as cousas el di é que lle di
que os rangos de valores que pode devolver.
É esencialmente negativo 2000000000 ao positivo 2 millóns, máis ou menos.
>> E ao parecer, todo isto tempo, aínda que nunca
tiña que comprobar a el, Se algo sae mal,
verifícase que todo Neste momento, ten getInt
foron retornando un especial constante, non nulo,
senón INT_MAX, que é convención só un programador.
Isto significa que aquí é un valor especial.
Asegúrese de comprobar iso, só tes no caso de algo correr mal.
Pero nunca se preocupou que ata a data,
porque unha vez máis, este destínase a simplificar.
>> Pero como é que se getInt aplicado?
Ben, un, non ten argumentos.
Sabemos diso.
El retorna un int.
Sabemos diso.
Entón, como é que funciona baixo o capo?
>> Polo tanto, non hai aparentemente un infinito ciclo, polo menos a aparición dun.
Teña en conta que estamos a usar getString.
Entón, iso é interesante. getInt chama a propia función, getString.
E agora por que isto podería ser o caso?
Por que estou a ser defensiva aquí na liña 165?
O que podería ocorrer en liña 164, só para quedar claro?
É a mesma resposta de antes.
Pode ser só falta de memoria.
Algo vai mal con getString, debemos ser capaces de tratar con isto.
E a razón de eu non retornan nulo é que, tecnicamente, null é un punteiro.
getInt ten que voltar un int.
Entón, eu teño arbitrariamente decidiu, esencialmente,
que 2 millóns, máis ou menos, vai ser un valor especial que eu nunca pode
realmente obter do usuario.
É só o valor que eu vou ao lixo para representar un código de erro.
>> Entón, agora, as cousas están un pouco de fantasía.
E non é así a mesma función como antes, pero é moi similar.
Entón, observe, eu declaro aquí, na liña 172, tanto un int n e un char c.
E entón eu uso esa liña funky, sscanf, o que se ve
non verifica a cadea desde o teclado.
Ergue-se unha secuencia existente que o usuario xa inseriu.
Entón, eu xa chamado getString, que significa que eu teño unha cadea na memoria.
sscanf é o que chamar unha función de análise.
El mira para a cadea teño introduciu, carácter por carácter,
e fai algo útil.
Esta secuencia é almacenado na cola.
E sei que só indo volver aquí e dicir, oh, OK,
Liguei para el non s neste momento, pero a liña.
>> E agora isto é un pouco diferente.
Pero isto significa que de forma eficaz, por razóns que de certa forma vai acenar as mans no día de hoxe,
que estamos comprobando a ver se o usuario inseriu
e int e quizais outro personaxe.
Se o usuario inseriu nun int, é vai ser almacenados en n, xa estou
pasando por esta dirección, o novo truco que vimos hoxe.
Se o usuario tamén ingresaran en como 123x, que x
vai acabar un carta en carácter c.
>> Agora verifícase que sscanf me vai dicir, de forma intelixente,
cantas variables foi sscanf correctamente poder cubrir.
Entón, por esta lóxica, a función Estou aplicando é getInt,
pero estou comprobando, , Potencialmente, para o usuario
ter ingresaran nun int seguido por outra cousa,
o que quero de sscanf valor de retorno realmente ser?
Se o obxectivo é obter só un int de usuario?
>> Entón, se sscanf retorno 2, o que significa isto?
O usuario inseriu algo así como, literalmente,
123x, o que é absurdo.
É unha condición de erro, e Quero comprobar para iso.
>> Polo tanto, se o usuario escribe isto en, polo Nesa lóxica, o que fai sscanf volver,
que diría?
Entón, que vai voltar 2, porque o 123 vai entrar aquí,
eo x vai acabar aquí.
Pero eu non quero que o x para estar cheo.
Quero sscanf só ter éxito en encher a primeira das súas variables.
E é por iso que eu quere sscanf para volver 1.
>> E se isto é un pouco sobre a cabeza para o momento, iso é totalmente bo.
Entenda, porén, que un dos valores de getInt e getString
é que estamos facendo unha peza de un chea de verificación de erros coma este para
que, ata agora, pode moi ben escribir nada no teclado,
e nós imos pegalo.
E por suposto, o persoal, non é sempre
ser a fonte de un erro no seu programa, porque estamos á defensiva
verificación de todos os estúpidos cousas que un usuario pode facer,
como escribir un texto, cando realmente quería int.
Así, para agora-- nós viremos de volta a este antes long--
pero todo este tempo, getString e getInt ter
foi por baixo do capuz con esta idea básica de enderezos de memoria.
>> Entón, agora, imos facer as cousas un pouco máis amigable.
Como pode lembrar, desde Binky última tempo-- se o meu rato vai cooperate-- así
tivemos ese código, que francamente, é moi absurda.
Este código obtén nada útil, pero foi o exemplo
que o profesor parlante utilizado para representar
o que estaba a ocorrer en un programa inclúen memoria.
>> Entón, imos recontar esa historia de super brevemente.
Estas dúas primeiras liñas, en Inglés, facer o que, diría?
Só no razoablemente humano, pero lixeiramente termos técnicos, tomar unha facada.
Audiencia: [inaudível].
>> DAVID J. Malan: OK, está establecendo enderezos para o seu variables x e y.
Non é ben así, xa xe y non son variables no sentido tradicional.
x e y son enderezos ou vai gardar o enderezo.
Entón, imos tratar unha vez máis.
Non é un mal comezo, con todo.
Si?
>> Audiencia: [inaudível].
DAVID J. Malan: Good.
Creo que é un pouco máis limpo.
Declarando dous punteiros, dous enteiros.
E nós estamos chamando-xe y.
Ou, se fose deseñar isto como unha imaxe de, de novo,
lembro moi simplemente que todos estamos facendo que a primeira liña
está deseñando un cadro como esta, con algún valor de lixo na mesma,
e chamando-x, e logo outra caixa como esta,
cun valor de lixo nel, chamando-y.
Xa declarou dous punteiros que, en última instancia
pode almacenar a dirección dun int.
Entón, iso é todo o que existe.
>> Entón, cando Binky fixo iso, o arxila só mirou como este.
E Nick só un tipo de embrulhado as frechas,
como se eles non están apuntando para calquera lugar en particular, porque son só
valores de lixo.
Eles non están explícitamente inicializar en calquera en particular.
>> Agora, a seguinte liña de código, recall, era iso.
Así, en razoablemente amigable, pero o inglés un pouco técnico,
o que é esa liña de código está facendo?
Si?
>> Audiencia: [inaudível].
>> DAVID J. Malan: Perfecto.
É atribución da parcela do memoria que é do tamaño dun int.
E iso é a metade da resposta.
Vostede respondeu á dereita metade da expresión.
O que está pasando na á esquerda do signo igual?
Si?
Audiencia: e atribúe á variable x?
>> DAVID J. Malan: e atribúe á variable x.
Entón, para recapitular, aloca lado dereito memoria suficiente para almacenar un int.
Pero malloc especificamente retorna a dirección
dese anaco de memoria, o que ten só proposto queda almacenado en x.
>> Entón, o que Nick fixo a última vez con Binky é el arrastrou este punteiro para fóra, o barro,
para apuntar agora nun anaco branco de memoria que coincide co tamaño dun int.
E, de feito, que supuxo para representar catro bytes.
>> Agora, a seguinte liña de código Fíxoo, estrela x recibe 42.
Entón 42 é simple na lado dereito, sentido da vida.
Lado esquerdo, estrela x significa o que?
Isto tamén pode ter gone-- está todo OK.
Está ben.
>> Audiencia: Basicamente, ir ao [inaudível]
DAVID J. Malan: Good.
Audiencia: [inaudível].
DAVID J. Malan: Exactamente.
Lado esquerdo significa ir x.
x é a dirección.
É como 33 Oxford Street, ou OX 1.
E estrela x significa ir a aquela tratar e poñer o que hai?
42.
>> Entón, en realidade, iso é o que Nick fixo.
Empezou con polo, esencialmente, mental
apuntando o dedo x, seguindo a frecha
á caixa branca do lado dereito banda, e poñer o número 42 alí.
Pero despois as cousas quedaron un pouco perigoso, non?
Binky está a piques de perder a cabeza.
>> Estrela y é igual a 13, a mala sorte, significa o que?
Entón medios y estrela ir ao enderezo en y.
Pero cal é a dirección en y?
Todo ben, é valor de lixo, non?
Eu tirei-o como un punto de interrogação.
Nick chamou-o como unha frecha enrolado.
E así que intenta facer estrela y dicindo ir alí,
pero non hai unha lexítima dirección, é unha situación falsa,
o programa vai fallar.
E a cabeza de Binky vai para voar aquí, como o fixo.
>> Entón, ao final, este programa era só plana fallo fora.
Era un programa de buggy.
E precisaba ser modificado.
E a única forma, realmente, para resolve-lo sería, por exemplo, esta liña de,
que nin sequera chegar, porque o programa caeu moi pronto.
Pero se tivésemos de solucionar isto, o que efecto que facer y iguais x ten?
Ben, esencialmente apunta y en calquera valor x está a apuntar.
>> Así, na historia de Nick, ou a historia de Binky, tanto
x e y foron apuntando o anaco branco de memoria,
de xeito que, por fin, cando non protagonizar y é igual a 13, unha vez máis,
acaba colocando 13 en o lugar apropiado.
Así, todas estas liñas son perfectamente lexítima, con excepción de un regalo,
cando isto aconteceu antes de ti efectivamente asignados y algún valor.
>> Agora, por sorte, non ten que razoar a través de todos
destes tipos de problemas no seu propio país.
Deixe-me ir adiante e abrir unha fiestra de terminal aquí
e abrir-se, por un momento, un super programa curto que
tamén é unha especie de inútil.
É feo.
Non conseguir calquera cousa útil.
Pero iso non demostrar problemas de memoria, así que imos dar un ollo.
>> Principal, super sinxelo.
Ao parecer, chama unha función, f, e, a continuación, retorna 0.
É medio difícil de romper iso.
Entón principal é moi bo, ata agora.
>> Así, f é problemático.
E só non poñer moito esforzo en nomealo
aquí, para manter o foco sobre o código.
f ten dúas liñas.
E imos ver o que está pasando agora.
Así, por unha banda aqui-- e déixeme facer
isto é consistente coa anterior example-- por unha banda,
á esquerda está facer o que, en inglés?
El é--
Audiencia: Creando un punteiro.
DAVID J. Malan: Creando un punteiro para un int e chamándoo x.
Entón, é a creación dunha desas caixas Eu sigo deseñando na pantalla táctil.
E agora, na man dereita banda, malloc, por suposto,
está alocando un bloque de memoria.
E só para quedar claro, como cantidade de memoria é, ao parecer,
distribución, se acaba de tipo de facer as contas aquí?
>> Polo tanto, é de 40 bytes.
E sei que só porque sei que un int, no aparello CS50, polo menos,
ten catro bytes.
Así, 10 veces 4 é 40.
Entón iso é almacenar un x, a dirección do primeiro de 40 Ints que
Foron atribuídos espazo de volta, cara atrás, cara atrás, cara atrás.
>> E iso é o que é importante sobre malloc.
Non é preciso un pouco de memoria aquí, un pouco aquí, un pouco aquí.
Dálle un anaco de memoria, contiguamente, a partir da operación
sistema.
>> Agora, o que sobre iso, x soporte de 10 é igual a 0?
Liña arbitraria de código.
Non conseguir calquera cousa útil.
Pero é interesante, porque x soporte 10--?
Si?
>> Audiencia: [inaudível]?
>> DAVID J. Malan: x soporte 10 non ten que ser nulo.
O detalle nulo só entra en xogo con cordas, no extremo dunha corda.
Pero un bo pensamento.
>> Que grande é esa matriz, aínda aínda que eu teña asignado 40 bytes?
É 0 a nove, non?
É 10 Ints, en total.
40 bytes, pero 10 Ints, indexados de 0 a 0.
>> Entón que é o que x soporte de 10?
En realidade, é un pouco valor de lixo descoñecido.
É a memoria que non pertence a min.
Non debería estar tocando que byte número 41, 42, 43, 44.
Estou un pouco lonxe de máis.
>> E, de feito, se eu executar este programa, pode moi ben funcionar.
Pero, ás veces, teñamos sorte.
E así, só para demostrar isso-- e, a verdade,
vostede non sabe antes non ele-- imos realizar este.
Non chegou a fallar.
>> Pero se eu cambiar isto, para exemplo, ser como 1.000,
para facelo realmente deliberada, xa veremos
se podemos facelo falla esta vez.
OK, non caeu.
Como preto de 100.000?
Imos refacelo lo, e agora executa-lo de novo.
Está ben.
Ufa.
Todo correcto.
Entón, ao parecer, unha vez máis, estes rutas de memoria, por así dicir,
son razoabelmente grande, para que poidamos ter sorte de novo e de novo.
Pero ao final, cando chegar ridículo e realmente ir lonxe na pantalla,
tocar memoria que realmente, realmente non pertence a vostede.
>> Pero, francamente, estes tipos de erros están indo
a ser cada vez máis difícil para descubrir por conta propia.
Pero, por sorte, como programadores, temos ferramentas que nos permiten facelo por nós.
Polo tanto, este é, quizais, un dos programas máis feos,
aínda máis fea do que a produción do gdb.
Pero sempre ten unha liña ou dous que son super útiles.
>> Valgrind é un programa que axuda non depurar un programa, de per si,
pero atopar relativas á memoria problemas, especialmente.
Esta será executado automaticamente o código para vostede e buscar polo menos dúas cousas.
Unha, que fixo algo accidental como a memoria de chamada
que non pertence a vostede?
El pode axudar a atopar estes casos.
>> E dous, que vai axudar atopa algo chamado
perdas de memoria, o que temos totalmente ignorado, inxenuamente,
por algún tempo e sorte.
Pero ao parecer, todo Neste momento, cando
chamou getString en moitos dos nosos programas,
está pregunta o funcionamento sistema para a memoria,
pero tes calquera lembranza de cada vez dándolle
cara atrás, facendo unalloc, ou libre, como se chama.
Non, porque nunca pediulle para facelo.
>> Pero todo este tempo, os programas ten escrito en C
foron baleirado de memoria, pedindo ao funcionamento
sistema para obter máis e máis memoria para cordas e outros enfeites,
pero nunca entrega-la de volta.
E agora isto é un pouco dunha simplificación,
pero se xa executar o Mac ou seu PC por algún tempo, a apertura
moitos programas, quizais pechar programas,
e aínda que o seu ordenador non caeu,
está quedando máis lento, como se fose realmente
usando unha gran cantidade de memoria ou recursos, a pesar de,
se non o é tocar o teclado,
que pode ser-- pero non podía always-- ser que os programas que está executando
ten-se perdas de memoria.
E eles seguen pedindo VOS para máis e máis memoria, pero esquece-lo,
en realidade non usalo, pero polo tanto, levando a memoria lonxe
doutros programas que poidan querer iso.
Entón, iso é unha explicación común.
Agora aquí é onde Valgrind de saída é completamente
atroz aos menos e máis cómodo iguais.
Pero o interesante material é ben aquí.
Está me dicindo unha gravación válido de tamaño catro acontece neste programa,
en particular, na liña 21 da memory.c.
>> Se eu ir á liña 21, hm, hai de feito é unha gravación válido de tamaño catro.
Por tamaño de catro?
Ben, este number-- e podería ser calquera cousa é un int.
Entón é catro bytes.
Entón, eu estou poñendo catro bytes onde non pertencen.
Iso é o que Valgrind está realmente dicindo.
Ademais, tamén será me diga, como veremos,
como realizar isto nun pset futuro, e cando xa se filtrou memoria, o que de feito
Eu teño, porque eu chamei malloc, pero eu realmente non teño
chamado, neste caso, libre, que imos finalmente ver
é o contrario de malloc.
>> Entón, agora, eu creo, un exemplo final.
Entón, este é un pouco máis arcano, pero é posible que
a maior razón para ter coidado coa memoria,
ea razón que moitos programas e / ou servidores web, ata hoxe,
son tomadas por bandidos nalgún lugar en internet que están de algunha maneira
envío de paquetes falsos ao servidor tentando comprometer as súas contas,
ou ter os seus datos, ou só xeralmente asumir unha máquina.
Buffer overflow, como o nome indica, medios
transbordador non un int, pero un tapón.
E un buffer é só un xeito elegante de dicir que é un monte de memoria.
>> E, de feito, chamei unha cadea antes de buffer, no canto de s.
Porque se é un buffer, como no sentido YouTube,
ou cando está a asistir a un vídeo, podes ver a palabra de tamponamento,
punto, punto, punto.
É incrible irritante.
E iso significa só que o seu reprodutor de vídeo
está intentando descargar lotes de bytes, os lotes de bytes
a partir dun vídeo de internet.
Pero é lento, polo que el está tratando descargar unha morea deles
para encher un tapón, un recipiente, de xeito que ten suficiente bytes que pode, entón,
amosar-lle o vídeo, sen deixar constantemente.
Pero acontece, pode teñen unha memoria intermedia para esta grande.
Pero tentar poñer esa cantidade de datos en iso, e moito as cousas malas poden ocorrer.
Así, por exemplo, imos ollar para este teaser final dun exemplo.
Este é outro programa que, a primeira vista,
non fai nada super útil.
Ten unha función principal que chama esa función, f.
E esa función, f, ata aquí, ten unha matriz de char, chamado c, de tamaño 12.
E el está a usar este nova función chamada strncpy.
>> Acontece que, con este sinxelo, simple liña de código, só dúas liñas,
fixemos todo o meu programa, e, polo tanto, todo o meu ordenador,
e miña conta de usuario, e meu disco conducir potencialmente vulnerábel a calquera persoa
quen sabe e é bo o suficiente para realizar este programa cunha certa liña de comandos
argumento.
Noutras palabras, se este cara mal pon dentro argvargv [1], escribindo
no teclado moi especialmente creado corda, non abc, 123, pero, esencialmente,
símbolos binarios que representan executable código, un programa que el ou ela escribiu:
con este programa sinxelo, que é representativa de miles de programas
que son igualmente vulnerables, atrévome a dicir, el ou ela pode chegar a eliminar todos
os arquivos no meu disco duro, obter un alerta chiscando para que el ou ela pode
escribir comandos por conta propia, enviar correo-e todos os ficheiros para min.
O que eu poida facer, el ou ela pode facer con este código.
>> Non imos solucionar isto bastante aínda.
E, de feito, que vai implicar un pouco de imaxe
como este, que nos imos en breve para entender todo mellor.
Pero por hoxe, imos rematar en o que é, por sorte, un pouco máis
comprensible broma xkcd, ata retomar a próxima vez.
Todo correcto.
Vexo vostedes o mércores.
>> [MÚSICA DE XOGO]
>> Orador: E agora, no fondo pensamentos, por Daven Farnham.
A memoria é como saltar nunha pila de follas de ouro nunha tarde de domingo.
Vento golpe, lanzando o seu hair-- oh, eu sinto falta dos días when--
>> [Risas]