1 00:00:00,000 --> 00:00:02,000 [Powered by Google Translate] [Valgrind] 2 00:00:02,000 --> 00:00:05,000 [Nate Hardison, Harvard University] 3 00:00:05,000 --> 00:00:07,000 Este é CS50, CS50.TV] 4 00:00:07,000 --> 00:00:10,000 Alguns dos erros mais difíceis de programas em C 5 00:00:10,000 --> 00:00:13,000 vêm da má gestão da memória. 6 00:00:13,000 --> 00:00:15,000 Há um número enorme de maneiras de estragar as coisas, 7 00:00:15,000 --> 00:00:17,000 incluindo alocar a quantidade errada de memória, 8 00:00:17,000 --> 00:00:20,000 esquecendo-se de inicializar variáveis, 9 00:00:20,000 --> 00:00:23,000 escrito antes ou após o final de um tampão, 10 00:00:23,000 --> 00:00:25,000 e liberando manter memória várias vezes. 11 00:00:25,000 --> 00:00:28,000 Os sintomas variam de falhas intermitentes 12 00:00:28,000 --> 00:00:30,000 para valores misteriosamente substituído, 13 00:00:30,000 --> 00:00:34,000 muitas vezes em locais e horários muito distantes do erro original. 14 00:00:34,000 --> 00:00:37,000 Detectar o problema observado de volta para a causa subjacente 15 00:00:37,000 --> 00:00:39,000 pode ser um desafio, 16 00:00:39,000 --> 00:00:42,000 mas, felizmente, existe um programa útil chamado Valgrind 17 00:00:42,000 --> 00:00:44,000 que podem fazer muita coisa para ajudar. 18 00:00:44,000 --> 00:00:47,000 >> Você executar um programa no Valgrind para permitir 19 00:00:47,000 --> 00:00:50,000 verificação extensa de alocações de heap de memória e acessos. 20 00:00:50,000 --> 00:00:53,000 Quando Valgrind detectar um problema, dá-lhe imediato, 21 00:00:53,000 --> 00:00:56,000 informação directa que lhe permite 22 00:00:56,000 --> 00:00:58,000 mais facilmente encontrar e corrigir o problema. 23 00:00:58,000 --> 00:01:01,000 Valgrind também relatórios sobre problemas de memória menos mortais, 24 00:01:01,000 --> 00:01:04,000 tais como vazamentos de memória, alocação de memória heap, 25 00:01:04,000 --> 00:01:07,000 e esquecer de libertá-la. 26 00:01:07,000 --> 00:01:10,000 Como nosso compilador Clang, em nosso depurador, GDB, 27 00:01:10,000 --> 00:01:14,000 Valgrind é software livre, e é instalado no aparelho. 28 00:01:14,000 --> 00:01:16,000 Valgrind é executado em seu executável, 29 00:01:16,000 --> 00:01:20,000 não o seu c. ou h. arquivos de código fonte, 30 00:01:20,000 --> 00:01:23,000 por isso não deixe de ter compilado uma cópia atualizada do seu programa 31 00:01:23,000 --> 00:01:25,000 usando Clang ou fazer. 32 00:01:25,000 --> 00:01:28,000 Em seguida, executando o seu programa sob Valgrind pode ser 33 00:01:28,000 --> 00:01:32,000 tão simples como prefixar o comando do programa com o padrão Valgrind palavra, 34 00:01:32,000 --> 00:01:35,000 que inicia Valgrind e executa o programa dentro dele. 35 00:01:35,000 --> 00:01:38,000 Ao iniciar, Valgrind faz algum complexo 36 00:01:38,000 --> 00:01:41,000 jiggering para configurar o executável para as verificações de memória, 37 00:01:41,000 --> 00:01:44,000 por isso pode demorar um pouco para se levantar e correr. 38 00:01:44,000 --> 00:01:48,000 O programa irá então executar normalmente, seja muito mais lentamente, 39 00:01:48,000 --> 00:01:52,000 e quando termina, Valgrind irá imprimir um resumo de seu uso de memória. 40 00:01:52,000 --> 00:01:58,000 Se tudo correr bem, ele será parecido com este: 41 00:01:58,000 --> 00:02:01,000 Neste caso,. / Clean_program 42 00:02:01,000 --> 00:02:04,000 é o caminho para o programa que eu quero correr. 43 00:02:04,000 --> 00:02:06,000 E enquanto este não tomar quaisquer argumentos, 44 00:02:06,000 --> 00:02:09,000 se isso acontecesse eu apenas tack-los para o final do comando, como de costume. 45 00:02:09,000 --> 00:02:12,000 Programa limpa é apenas um programa um pouco bobo eu criei 46 00:02:12,000 --> 00:02:15,000 que aloca espaço para um bloco de inteiros na pilha, 47 00:02:15,000 --> 00:02:19,000 colocar alguns valores dentro deles, e libera o bloco inteiro. 48 00:02:19,000 --> 00:02:23,000 Isto é o que você está atirando para, sem erros e sem vazamentos. 49 00:02:23,000 --> 00:02:27,000 >> Outra métrica importante é o número total de bytes atribuídos. 50 00:02:27,000 --> 00:02:32,000 Dependendo do programa, se suas atribuições estão nas megabytes ou mais, 51 00:02:32,000 --> 00:02:34,000 provavelmente você está fazendo algo errado. 52 00:02:34,000 --> 00:02:37,000 Você está desnecessariamente armazenar duplicatas? 53 00:02:37,000 --> 00:02:40,000 Você está usando a pilha para armazenamento, quando seria melhor usar a pilha? 54 00:02:40,000 --> 00:02:43,000 Assim, erros de memória podem ser verdadeiramente mal. 55 00:02:43,000 --> 00:02:46,000 Os mais evidentes causar acidentes espetaculares, 56 00:02:46,000 --> 00:02:49,000 mas, mesmo assim, ele ainda pode ser difícil identificar 57 00:02:49,000 --> 00:02:51,000 exatamente o que levou ao acidente. 58 00:02:51,000 --> 00:02:54,000 Mais insidiosamente, um programa com um erro de memória 59 00:02:54,000 --> 00:02:56,000 ainda pode compilar limpa 60 00:02:56,000 --> 00:02:58,000 e pode ainda parecem funcionar corretamente 61 00:02:58,000 --> 00:03:01,000 porque você conseguiu ter sorte na maioria das vezes. 62 00:03:01,000 --> 00:03:04,000 Depois de vários "bons resultados", 63 00:03:04,000 --> 00:03:07,000 você pode apenas pensar que um acidente é um golpe de sorte do computador, 64 00:03:07,000 --> 00:03:10,000 mas o computador nunca está errado. 65 00:03:10,000 --> 00:03:13,000 >> Correndo Valgrind pode ajudá-lo a rastrear a causa de erros de memória visíveis 66 00:03:13,000 --> 00:03:18,000 bem como encontrar espreita erros você nem sabe ainda sobre. 67 00:03:18,000 --> 00:03:22,000 Cada vez Valgrind detectar um problema, ele imprime informações sobre o que observaram. 68 00:03:22,000 --> 00:03:24,000 Cada item é bastante concisa - 69 00:03:24,000 --> 00:03:27,000 a linha da fonte da instrução ofender, qual é o problema, 70 00:03:27,000 --> 00:03:30,000 Informações e um pouco sobre a memória envolvida - 71 00:03:30,000 --> 00:03:34,000 mas muitas vezes é informação suficiente para direcionar sua atenção para o lugar certo. 72 00:03:34,000 --> 00:03:37,000 Aqui é um exemplo de execução no Valgrind um programa de buggy 73 00:03:37,000 --> 00:03:40,000 que faz uma leitura inválido de memória heap. 74 00:03:40,000 --> 00:03:49,000 Nós vemos nenhum erro ou aviso na compilação. 75 00:03:49,000 --> 00:03:53,000 Uh-oh, o resumo de erro diz que há dois erros - 76 00:03:53,000 --> 00:03:56,000 duas leituras inválido de tamanho 4 - bytes, que é. 77 00:03:56,000 --> 00:04:01,000 Tanto maus lê ocorreu na função principal de invalid_read.c, 78 00:04:01,000 --> 00:04:04,000 o primeiro na linha 16 e o ​​segundo na linha 19. 79 00:04:04,000 --> 00:04:06,000 Vamos olhar para o código. 80 00:04:06,000 --> 00:04:11,000 Parece que a primeira chamada para printf tenta ler um int passado o fim do nosso bloco de memória. 81 00:04:11,000 --> 00:04:13,000 Se olharmos para trás na saída do Valgrind, 82 00:04:13,000 --> 00:04:16,000 vemos que Valgrind nos disse exatamente isso. 83 00:04:16,000 --> 00:04:19,000 O endereço que estamos tentando ler começa 0 bytes 84 00:04:19,000 --> 00:04:22,000 após o fim do bloco de 16 bytes de tamanho - 85 00:04:22,000 --> 00:04:25,000 quatro de 32 bits ints que alocados. 86 00:04:25,000 --> 00:04:29,000 Ou seja, o endereço que estávamos tentando ler começa logo no final do nosso bloco, 87 00:04:29,000 --> 00:04:32,000 assim como vemos em nosso chamado mau printf. 88 00:04:32,000 --> 00:04:36,000 Agora, inválida leituras pode não parecer tão grande de um negócio, 89 00:04:36,000 --> 00:04:39,000 mas se você está usando esses dados para controlar o fluxo de seu programa - 90 00:04:39,000 --> 00:04:42,000 por exemplo, como parte de uma instrução if ou loop - 91 00:04:42,000 --> 00:04:45,000 então as coisas podem ir mal em silêncio. 92 00:04:45,000 --> 00:04:47,000 Veja como eu pode executar o programa invalid_read 93 00:04:47,000 --> 00:04:50,000 e nada fora do comum acontece. 94 00:04:50,000 --> 00:04:52,000 Assustador, não? 95 00:04:52,000 --> 00:04:56,000 >> Agora, vamos olhar mais alguns tipos de erros que você pode encontrar em seu código, 96 00:04:56,000 --> 00:04:59,000 e vamos ver como Valgrind detecta. 97 00:04:59,000 --> 00:05:01,000 Nós só vimos um exemplo de um invalid_read, 98 00:05:01,000 --> 00:05:04,000 então agora vamos verificar um invalid_write. 99 00:05:04,000 --> 00:05:09,000 Mais uma vez, nenhum erro ou aviso na compilação. 100 00:05:09,000 --> 00:05:12,000 Ok, Valgrind diz que há dois erros neste programa - 101 00:05:12,000 --> 00:05:15,000 e invalid_write e um invalid_read. 102 00:05:15,000 --> 00:05:18,000 Vamos verificar este código. 103 00:05:18,000 --> 00:05:21,000 Parece que temos uma instância do strlen clássico mais um bug. 104 00:05:21,000 --> 00:05:24,000 O código não malloc um byte extra de espaço 105 00:05:24,000 --> 00:05:26,000 para o personagem / 0, 106 00:05:26,000 --> 00:05:30,000 por isso, quando str cópia foi para escrevê-lo em ssubstrlen "CS50 rocks!" 107 00:05:30,000 --> 00:05:33,000 escreveu um byte após o final do nosso bloco. 108 00:05:33,000 --> 00:05:36,000 O invalid_read vem quando nós fazemos a nossa chamada para printf. 109 00:05:36,000 --> 00:05:40,000 Printf acaba de ler memória inválido, quando ele lê o / 0 caráter 110 00:05:40,000 --> 00:05:43,000 como ele olha para o final deste corda E é impressão. 111 00:05:43,000 --> 00:05:45,000 Mas nada disso escapou Valgrind. 112 00:05:45,000 --> 00:05:48,000 Vemos que chamou a invalid_write como parte da cópia de str 113 00:05:48,000 --> 00:05:51,000 na linha 11 do principal, eo invalid_read é parte do printf. 114 00:05:51,000 --> 00:05:54,000 Rock on, Valgrind. 115 00:05:54,000 --> 00:05:57,000 Novamente, isso pode não parecer um grande negócio. 116 00:05:57,000 --> 00:06:00,000 Podemos executar este programa mais e mais fora de Valgrind 117 00:06:00,000 --> 00:06:03,000 e não ver nenhum sintoma de erro. 118 00:06:03,000 --> 00:06:06,000 >> No entanto, vamos olhar para uma pequena variação dessa para ver 119 00:06:06,000 --> 00:06:09,000 como as coisas podem ficar muito ruim. 120 00:06:09,000 --> 00:06:14,000 Assim, concedeu, estamos abusando de coisas mais do que apenas um pouco neste código. 121 00:06:14,000 --> 00:06:17,000 Estamos apenas a alocação de espaço na pilha para duas cordas 122 00:06:17,000 --> 00:06:19,000 o comprimento de CS50 rochas, 123 00:06:19,000 --> 00:06:22,000 desta vez, lembrando o / 0 personagem. 124 00:06:22,000 --> 00:06:25,000 Mas, então, jogar em uma seqüência super-longa no bloco de memória 125 00:06:25,000 --> 00:06:27,000 S que está apontando. 126 00:06:27,000 --> 00:06:30,000 Qual será o efeito que tem sobre o bloco de memória que aponta para T? 127 00:06:30,000 --> 00:06:34,000 Bem, se os pontos de T a memória que é apenas ao lado S, 128 00:06:34,000 --> 00:06:37,000 vindo logo depois, 129 00:06:37,000 --> 00:06:39,000 então nós poderia ter escrito sobre parte de T. 130 00:06:39,000 --> 00:06:41,000 Vamos executar esse código. 131 00:06:41,000 --> 00:06:43,000 Olhe para o que aconteceu. 132 00:06:43,000 --> 00:06:47,000 As cordas que armazenados em nossos blocos de heap ambos pareciam ter impressos corretamente. 133 00:06:47,000 --> 00:06:49,000 Nada parece errado em tudo. 134 00:06:49,000 --> 00:06:52,000 No entanto, vamos voltar para o nosso código e 135 00:06:52,000 --> 00:06:55,000 comente a linha onde copiar CS50 rochas 136 00:06:55,000 --> 00:06:59,000 no bloco de memória em segundo lugar, apontada por t. 137 00:06:59,000 --> 00:07:02,000 Agora, quando executar este código que deve 138 00:07:02,000 --> 00:07:06,000 só ver o conteúdo do primeiro bloco de memória imprimir. 139 00:07:06,000 --> 00:07:09,000 Whoa, mesmo que não fez cópia str 140 00:07:09,000 --> 00:07:12,000 quaisquer caracteres no bloco heap segundo, aquele apontado por T, 141 00:07:12,000 --> 00:07:15,000 temos uma impressão. 142 00:07:15,000 --> 00:07:18,000 De fato, a seqüência de nós recheado em nosso primeiro bloco 143 00:07:18,000 --> 00:07:21,000 invadiram o primeiro bloco e para dentro do segundo bloco, 144 00:07:21,000 --> 00:07:23,000 fazendo com que tudo pareça normal. 145 00:07:23,000 --> 00:07:26,000 Valgrind, porém, diz-nos a história verdadeira. 146 00:07:26,000 --> 00:07:28,000 Lá vamos nós. 147 00:07:28,000 --> 00:07:32,000 Todos aqueles inválido lê e escreve. 148 00:07:32,000 --> 00:07:36,000 >> Vejamos um exemplo de outro tipo de erro. 149 00:07:36,000 --> 00:07:39,000 Aqui fazemos algo bastante infeliz. 150 00:07:39,000 --> 00:07:41,000 Nós agarrar espaço para um int na pilha, 151 00:07:41,000 --> 00:07:45,000 e inicializar um ponteiro int - p - para apontar para esse espaço. 152 00:07:45,000 --> 00:07:48,000 No entanto, enquanto o nosso ponteiro é inicializado, 153 00:07:48,000 --> 00:07:52,000 os dados que ele está apontando para o que acaba de lixo é em que parte da pilha. 154 00:07:52,000 --> 00:07:55,000 Então, quando temos de carregar esses dados em int i, 155 00:07:55,000 --> 00:07:57,000 que tecnicamente inicializar i, 156 00:07:57,000 --> 00:08:00,000 mas fazê-lo com dados de lixo. 157 00:08:00,000 --> 00:08:03,000 A chamada para afirmar, que é uma macro de depuração útil 158 00:08:03,000 --> 00:08:06,000 definido no apropriadamente chamado biblioteca afirmar, 159 00:08:06,000 --> 00:08:09,000 irá abortar o programa se a sua condição de teste falhar. 160 00:08:09,000 --> 00:08:11,000 Isto é, se eu não for 0. 161 00:08:11,000 --> 00:08:14,000 Dependendo do que foi no espaço de pilha, apontado por p, 162 00:08:14,000 --> 00:08:18,000 este programa pode funcionar algumas vezes e não em outros momentos. 163 00:08:18,000 --> 00:08:20,000 Se funcionar, nós estamos apenas começando sorte. 164 00:08:20,000 --> 00:08:24,000 O compilador não vai pegar esse erro, mas Valgrind vontade certeza. 165 00:08:24,000 --> 00:08:28,000 Há que ver o erro decorrente de nosso uso desses dados sucata. 166 00:08:28,000 --> 00:08:32,000 >> Quando você aloca memória heap, mas não desalocar-lo ou libertá-lo, 167 00:08:32,000 --> 00:08:34,000 que é chamado de uma fuga. 168 00:08:34,000 --> 00:08:37,000 Para um pequeno programa de curta duração que corre e sai imediatamente, 169 00:08:37,000 --> 00:08:39,000 vazamentos são bastante inofensivos, 170 00:08:39,000 --> 00:08:42,000 mas para um projeto de maior porte e / ou longevidade, 171 00:08:42,000 --> 00:08:46,000 até mesmo um pequeno vazamento pode agravar em algo maior. 172 00:08:46,000 --> 00:08:49,000 Para CS50, nós esperamos que você 173 00:08:49,000 --> 00:08:51,000 cuidar de libertar toda a memória heap que você alocar, 174 00:08:51,000 --> 00:08:54,000 desde que nós queremos que você construa as habilidades para lidar adequadamente com o processo manual 175 00:08:54,000 --> 00:08:56,000 exigida pela C. 176 00:08:56,000 --> 00:08:59,000 Para isso, o programa deve ter uma exata 177 00:08:59,000 --> 00:09:03,000 um-para-um entre malloc e chamadas gratuitas. 178 00:09:03,000 --> 00:09:06,000 Felizmente, Valgrind pode ajudá-lo com vazamentos de memória também. 179 00:09:06,000 --> 00:09:09,000 Aqui está um programa furado chamado leak.c que aloca 180 00:09:09,000 --> 00:09:13,000 espaço na pilha, escreve para ele, mas não libertá-lo. 181 00:09:13,000 --> 00:09:16,000 Nós compilar com Fazer e executá-lo em Valgrind, 182 00:09:16,000 --> 00:09:18,000 e vemos que, enquanto temos nenhum erro de memória, 183 00:09:18,000 --> 00:09:20,000 temos um vazamento. 184 00:09:20,000 --> 00:09:23,000 Há 16 bytes definitivamente perdidos, 185 00:09:23,000 --> 00:09:27,000 o que significa que o ponteiro para que a memória não estava no escopo quando o programa foi encerrado. 186 00:09:27,000 --> 00:09:30,000 Agora, Valgrind não nos dá uma tonelada de informações sobre o vazamento, 187 00:09:30,000 --> 00:09:35,000 mas se seguirmos essa pequena nota que ele dá em direcção ao fundo do seu relatório 188 00:09:35,000 --> 00:09:38,000 executar novamente com - leak-check = total 189 00:09:38,000 --> 00:09:41,000 para ver os detalhes completos de memória vazada, 190 00:09:41,000 --> 00:09:44,000 vamos obter mais informações. 191 00:09:44,000 --> 00:09:46,000 Agora, no resumo heap, 192 00:09:46,000 --> 00:09:50,000 Valgrind nos diz onde a memória que se perdeu foi inicialmente atribuído. 193 00:09:50,000 --> 00:09:52,000 Assim como sabemos de olhar no código fonte, 194 00:09:52,000 --> 00:09:55,000 Valgrind nos informa que vazou a memória 195 00:09:55,000 --> 00:09:58,000 alocada com uma chamada a malloc na linha 8 da leak.c 196 00:09:58,000 --> 00:10:00,000 na função principal. 197 00:10:00,000 --> 00:10:02,000 Muito bacana. 198 00:10:02,000 --> 00:10:04,000 >> Valgrind categoriza vazamentos usando estes termos: 199 00:10:04,000 --> 00:10:07,000 Definitivamente perdido - isto é memória alocada pilha 200 00:10:07,000 --> 00:10:10,000 para que o programa não tem um ponteiro. 201 00:10:10,000 --> 00:10:14,000 Valgrind sabe que você já teve o ponteiro, mas, desde então, perdeu a noção do mesmo. 202 00:10:14,000 --> 00:10:17,000 Esta memória é definitivamente vazou. 203 00:10:17,000 --> 00:10:20,000 Indiretamente perdido - isto é memória alocada pilha 204 00:10:20,000 --> 00:10:24,000 a que apenas os apontadores para isso também são perdidas. 205 00:10:24,000 --> 00:10:27,000 Por exemplo, se você perdeu o ponteiro para o primeiro nó de uma lista ligada, 206 00:10:27,000 --> 00:10:30,000 em seguida, o primeiro nó si seria definitivamente perdidas, 207 00:10:30,000 --> 00:10:34,000 enquanto todos os nós subseqüentes seriam indiretamente perdido. 208 00:10:34,000 --> 00:10:37,000 Possivelmente perdeu - esta é a memória alocada pilha 209 00:10:37,000 --> 00:10:41,000 ao qual Valgrind não pode ter a certeza se existe um ponteiro ou não. 210 00:10:41,000 --> 00:10:44,000 Ainda acessível é a memória alocada pilha 211 00:10:44,000 --> 00:10:47,000 em que o programa tem ainda um ponteiro na saída, 212 00:10:47,000 --> 00:10:50,000 o que normalmente significa que uma variável global pontos para ele. 213 00:10:50,000 --> 00:10:53,000 Para verificar esses vazamentos, você também tem que incluir a opção 214 00:10:53,000 --> 00:10:55,000 - Ainda alcançável = yes 215 00:10:55,000 --> 00:10:58,000 na sua invocação de Valgrind. 216 00:10:58,000 --> 00:11:01,000 >> Estes casos podem requerer diferentes estratégias diferentes para limpá-las para cima, 217 00:11:01,000 --> 00:11:05,000 mas vazamentos devem ser eliminados. 218 00:11:05,000 --> 00:11:08,000 Infelizmente, consertar vazamentos pode ser difícil de fazer, 219 00:11:08,000 --> 00:11:11,000 já que as chamadas incorretas a livre pode explodir o seu programa. 220 00:11:11,000 --> 00:11:14,000 Por exemplo, se olharmos para invalid_free.c, 221 00:11:14,000 --> 00:11:18,000 vemos um exemplo de desalocação de memória ruim. 222 00:11:18,000 --> 00:11:21,000 O que deveria ser uma única chamada para liberar todo o bloco 223 00:11:21,000 --> 00:11:24,000 de memória apontada por int_block, 224 00:11:24,000 --> 00:11:27,000 em vez disso se tornar uma tentativa de libertar cada seção int porte 225 00:11:27,000 --> 00:11:29,000 da memória individualmente. 226 00:11:29,000 --> 00:11:32,000 Isto irá falhar catastroficamente. 227 00:11:32,000 --> 00:11:34,000 Boom! O que um erro. 228 00:11:34,000 --> 00:11:36,000 Isto definitivamente não é bom. 229 00:11:36,000 --> 00:11:39,000 Se você está preso com esse tipo de erro, embora, e você não sabe para onde olhar, 230 00:11:39,000 --> 00:11:41,000 cair para trás em seu novo melhor amigo. 231 00:11:41,000 --> 00:11:44,000 Você adivinhou - Valgrind. 232 00:11:44,000 --> 00:11:47,000 Valgrind, como sempre, sabe exatamente o que está acontecendo. 233 00:11:47,000 --> 00:11:50,000 As contagens alloc e livre não combinam. 234 00:11:50,000 --> 00:11:52,000 Temos um alloc e 4 liberta. 235 00:11:52,000 --> 00:11:55,000 E Valgrind também nos diz que a chamada má primeira livre - 236 00:11:55,000 --> 00:11:58,000 o que desencadeou a blowup - está vindo - 237 00:11:58,000 --> 00:12:00,000 linha 16. 238 00:12:00,000 --> 00:12:03,000 Como você pode ver, as chamadas para libertar maus são muito ruins, 239 00:12:03,000 --> 00:12:05,000 por isso recomendamos deixar o seu programa de vazamento 240 00:12:05,000 --> 00:12:08,000 enquanto você está trabalhando para conseguir a funcionalidade correta. 241 00:12:08,000 --> 00:12:12,000 Comece procurando vazamentos somente após o programa está funcionando corretamente, 242 00:12:12,000 --> 00:12:14,000 sem quaisquer outros erros. 243 00:12:14,000 --> 00:12:16,000 >> E isso é tudo o que temos para este vídeo. 244 00:12:16,000 --> 00:12:18,000 Agora, o que você está esperando? 245 00:12:18,000 --> 00:12:21,000 Ir executar Valgrind em seus programas agora. 246 00:12:21,000 --> 00:12:25,000 Meu nome é Nate Hardison. Este é CS50. [CS50.TV]