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 Algúns dos erros máis difíciles de programas en C 5 00:00:10,000 --> 00:00:13,000 veñen da mala xestión da memoria. 6 00:00:13,000 --> 00:00:15,000 Hai un número enorme de formas de romper as cousas, 7 00:00:15,000 --> 00:00:17,000 incluíndo reservar a cantidade errónea de memoria, 8 00:00:17,000 --> 00:00:20,000 esquecéndose de arrincar variables, 9 00:00:20,000 --> 00:00:23,000 escrito antes ou despois do final dun tapón, 10 00:00:23,000 --> 00:00:25,000 e liberando manter memoria varias veces. 11 00:00:25,000 --> 00:00:28,000 Os síntomas varían de erros intermitentes 12 00:00:28,000 --> 00:00:30,000 para valores misteriosamente substituído, 13 00:00:30,000 --> 00:00:34,000 moitas veces en lugares e horarios moi distantes do erro orixinal. 14 00:00:34,000 --> 00:00:37,000 Detectar o problema observado de volta para a causa subxacente 15 00:00:37,000 --> 00:00:39,000 pode ser un desafío, 16 00:00:39,000 --> 00:00:42,000 pero, por sorte, existe un programa útil chamado Valgrind 17 00:00:42,000 --> 00:00:44,000 que poden facer moita cousa para axudar. 18 00:00:44,000 --> 00:00:47,000 >> Vostede executar un programa no Valgrind para permitir 19 00:00:47,000 --> 00:00:50,000 verificación extensa de alocações de heap de memoria e accesos. 20 00:00:50,000 --> 00:00:53,000 Cando Valgrind detectar un problema, dálle inmediato, 21 00:00:53,000 --> 00:00:56,000 información directa que lle permite 22 00:00:56,000 --> 00:00:58,000 máis facilmente atopar e resolver o problema. 23 00:00:58,000 --> 00:01:01,000 Valgrind tamén informes sobre problemas de memoria menos mortais, 24 00:01:01,000 --> 00:01:04,000 como vazamentos de memoria, distribución de memoria heap, 25 00:01:04,000 --> 00:01:07,000 e esquecer de liberar-la. 26 00:01:07,000 --> 00:01:10,000 Como o noso compilador Clang, no noso depurador, GDB, 27 00:01:10,000 --> 00:01:14,000 Valgrind é software libre, e é instalado no aparello. 28 00:01:14,000 --> 00:01:16,000 Valgrind é executado no seu executable, 29 00:01:16,000 --> 00:01:20,000 non o seu c. ou h. ficheiros de código fonte, 30 00:01:20,000 --> 00:01:23,000 por que non deixe de ter compilado unha copia actualizada do seu programa 31 00:01:23,000 --> 00:01:25,000 usando Clang ou facer. 32 00:01:25,000 --> 00:01:28,000 A continuación, executando o seu programa baixo Valgrind pode ser 33 00:01:28,000 --> 00:01:32,000 tan sinxelo coma prefixar o mando do programa co estándar Valgrind palabra, 34 00:01:32,000 --> 00:01:35,000 que inicia Valgrind e executa o programa dentro del. 35 00:01:35,000 --> 00:01:38,000 Ao iniciarse, Valgrind fai algún complexo 36 00:01:38,000 --> 00:01:41,000 jiggering para configurar o executable para as comprobacións de memoria, 37 00:01:41,000 --> 00:01:44,000 por iso pode levar un pouco para se erguer e executar. 38 00:01:44,000 --> 00:01:48,000 O programa ha entón executar normalmente, é moi máis lentamente, 39 00:01:48,000 --> 00:01:52,000 e cando remata, Valgrind ha imprimir un resumo do seu uso de memoria. 40 00:01:52,000 --> 00:01:58,000 Se todo funcionar ben, será coma este: 41 00:01:58,000 --> 00:02:01,000 Neste caso,. / Clean_program 42 00:02:01,000 --> 00:02:04,000 é o camiño para o programa que quero correr. 43 00:02:04,000 --> 00:02:06,000 E mentres este non tomar calquera argumentos, 44 00:02:06,000 --> 00:02:09,000 se iso acontecese eu só Tack-los para o final do mando, como de costume. 45 00:02:09,000 --> 00:02:12,000 Programa limpa é só un programa un pouco parvo eu creei 46 00:02:12,000 --> 00:02:15,000 que aloca espazo para un bloque de enteiros na pila, 47 00:02:15,000 --> 00:02:19,000 poñer algúns valores dentro deles, e libera o bloque enteiro. 48 00:02:19,000 --> 00:02:23,000 Isto é o que está tirando para, sen erros e sen vazamentos. 49 00:02:23,000 --> 00:02:27,000 >> Outra métrica importante é o número total de bytes asignados. 50 00:02:27,000 --> 00:02:32,000 Dependendo do programa, as súas atribucións están nas megabytes ou máis, 51 00:02:32,000 --> 00:02:34,000 probablemente está facendo algo mal. 52 00:02:34,000 --> 00:02:37,000 Vostede está innecesariamente almacenar duplicados? 53 00:02:37,000 --> 00:02:40,000 Está a usar a pila para almacenamento, cando sería mellor usar a pila? 54 00:02:40,000 --> 00:02:43,000 Así, erros de memoria poden ser verdadeiramente mal. 55 00:02:43,000 --> 00:02:46,000 Os máis evidentes causar accidentes espectaculares, 56 00:02:46,000 --> 00:02:49,000 pero, aínda así, el tamén pode ser difícil identificar 57 00:02:49,000 --> 00:02:51,000 exactamente o que levou ao accidente. 58 00:02:51,000 --> 00:02:54,000 Máis insidiosamente, un programa con un erro de memoria 59 00:02:54,000 --> 00:02:56,000 Aínda pode compilar limpa 60 00:02:56,000 --> 00:02:58,000 e pode parecen funcionar correctamente 61 00:02:58,000 --> 00:03:01,000 porque conseguiu ter sorte na maioría das veces. 62 00:03:01,000 --> 00:03:04,000 Despois de varios "bos resultados", 63 00:03:04,000 --> 00:03:07,000 pode só pensar que un accidente é un golpe de sorte do ordenador, 64 00:03:07,000 --> 00:03:10,000 pero o ordenador non está mal. 65 00:03:10,000 --> 00:03:13,000 >> Correndo Valgrind pode axudar a rastrexar a causa de erros de memoria visibles 66 00:03:13,000 --> 00:03:18,000 así como atopar espreita erros que nin sabe aínda sobre. 67 00:03:18,000 --> 00:03:22,000 Cada vez Valgrind detectar un problema, el imprime información acerca do que observaron. 68 00:03:22,000 --> 00:03:24,000 Cada elemento é moi concisa - 69 00:03:24,000 --> 00:03:27,000 a liña da fonte da instrución ofender, cal é o problema, 70 00:03:27,000 --> 00:03:30,000 Información e un pouco sobre a memoria utilizada - 71 00:03:30,000 --> 00:03:34,000 pero moitas veces é suficiente información para dirixir a súa atención para o lugar seguro. 72 00:03:34,000 --> 00:03:37,000 Aquí é un exemplo de execución no Valgrind un programa de buggy 73 00:03:37,000 --> 00:03:40,000 que fai unha lectura incorrecta de memoria heap. 74 00:03:40,000 --> 00:03:49,000 Vemos ningún erro ou aviso na compilación. 75 00:03:49,000 --> 00:03:53,000 Uh-oh, un resumo de erro di que hai dous erros - 76 00:03:53,000 --> 00:03:56,000 dúas lecturas válido de tamaño 4 - bytes, que é. 77 00:03:56,000 --> 00:04:01,000 Tanto malos le ocorreu na función principal de invalid_read.c, 78 00:04:01,000 --> 00:04:04,000 o primeiro na liña 16 e o ​​segundo na liña 19. 79 00:04:04,000 --> 00:04:06,000 Imos mirar para o código. 80 00:04:06,000 --> 00:04:11,000 Parece que a primeira chamada printf intenta ler un int pasado fin do noso bloque de memoria. 81 00:04:11,000 --> 00:04:13,000 Se miramos cara atrás na saída do Valgrind, 82 00:04:13,000 --> 00:04:16,000 vemos que Valgrind nos dixo exactamente isto. 83 00:04:16,000 --> 00:04:19,000 O enderezo que estamos tentando ler comeza 0 bytes 84 00:04:19,000 --> 00:04:22,000 tras o fin do bloque de 16 bytes de tamaño - 85 00:04:22,000 --> 00:04:25,000 catro de 32 bits ints que alocados. 86 00:04:25,000 --> 00:04:29,000 Ou sexa, o enderezo que estabamos intentando ler comeza pronto a finais do noso bloque, 87 00:04:29,000 --> 00:04:32,000 así como vemos no noso chamado mal printf. 88 00:04:32,000 --> 00:04:36,000 Agora, non é válida Lecturas pode non parecer tan grande dun negocio, 89 00:04:36,000 --> 00:04:39,000 pero se está a usar estes datos para controlar o fluxo do seu programa - 90 00:04:39,000 --> 00:04:42,000 por exemplo, como parte dunha instrución if ou loop - 91 00:04:42,000 --> 00:04:45,000 entón as cousas poden ir mal en silencio. 92 00:04:45,000 --> 00:04:47,000 Vexa como eu pode executar o programa invalid_read 93 00:04:47,000 --> 00:04:50,000 e nada fóra do común acontece. 94 00:04:50,000 --> 00:04:52,000 Asustado, non? 95 00:04:52,000 --> 00:04:56,000 >> Agora, imos ollar algúns tipos de erros que pode atopar no seu código, 96 00:04:56,000 --> 00:04:59,000 e imos ver como Valgrind detecta. 97 00:04:59,000 --> 00:05:01,000 Nós só vimos un exemplo dun invalid_read, 98 00:05:01,000 --> 00:05:04,000 entón agora imos comprobar un invalid_write. 99 00:05:04,000 --> 00:05:09,000 Unha vez máis, ningún erro ou aviso na compilación. 100 00:05:09,000 --> 00:05:12,000 Ok, Valgrind di que hai dous erros neste programa - 101 00:05:12,000 --> 00:05:15,000 e invalid_write e un invalid_read. 102 00:05:15,000 --> 00:05:18,000 Imos comprobar este código. 103 00:05:18,000 --> 00:05:21,000 Parece que temos unha instancia do strlen clásico un erro. 104 00:05:21,000 --> 00:05:24,000 O código non malloc un byte extra de espazo 105 00:05:24,000 --> 00:05:26,000 para o personaxe / 0, 106 00:05:26,000 --> 00:05:30,000 por iso, cando str copia foi para gravala-lo en ssubstrlen "CS50 rocks!" 107 00:05:30,000 --> 00:05:33,000 escribiu un byte despois do final do noso bloque. 108 00:05:33,000 --> 00:05:36,000 O invalid_read vén cando nós facemos a nosa chamada printf. 109 00:05:36,000 --> 00:05:40,000 Printf acaba de ler memoria válido, cando le o / 0 carácter 110 00:05:40,000 --> 00:05:43,000 como mira cara ao final deste corda e é impresión. 111 00:05:43,000 --> 00:05:45,000 Pero nada diso escapou Valgrind. 112 00:05:45,000 --> 00:05:48,000 Vemos que chamou a invalid_write como parte da copia de str 113 00:05:48,000 --> 00:05:51,000 na liña 11 do principal eo invalid_read é parte do printf. 114 00:05:51,000 --> 00:05:54,000 Rock en, Valgrind. 115 00:05:54,000 --> 00:05:57,000 De novo, isto pode non parecer un gran negocio. 116 00:05:57,000 --> 00:06:00,000 Podemos executar este programa máis e máis fóra de Valgrind 117 00:06:00,000 --> 00:06:03,000 e non ver ningún síntoma de erro. 118 00:06:03,000 --> 00:06:06,000 >> Con todo, imos ollar a unha pequena variación desa ver 119 00:06:06,000 --> 00:06:09,000 como as cousas poden ser moi malo. 120 00:06:09,000 --> 00:06:14,000 Así, concedeu, estamos abusando de cousas máis que un pouco neste código. 121 00:06:14,000 --> 00:06:17,000 Estamos só a distribución de espazo na pila para dúas cordas 122 00:06:17,000 --> 00:06:19,000 a lonxitude de CS50 rochas, 123 00:06:19,000 --> 00:06:22,000 esta vez, lembrando o / 0 personaxe. 124 00:06:22,000 --> 00:06:25,000 Pero, entón, xogar nunha secuencia super-longa no bloque de memoria 125 00:06:25,000 --> 00:06:27,000 S que está apuntando. 126 00:06:27,000 --> 00:06:30,000 Cal será o efecto que ten sobre o bloque de memoria que apunta a T? 127 00:06:30,000 --> 00:06:34,000 Ben, se os puntos de T a memoria que é só ao lado S, 128 00:06:34,000 --> 00:06:37,000 está despois, 129 00:06:37,000 --> 00:06:39,000 entón podería ter escrito sobre parte T. 130 00:06:39,000 --> 00:06:41,000 Imos executar este código. 131 00:06:41,000 --> 00:06:43,000 Olle para o que pasou. 132 00:06:43,000 --> 00:06:47,000 As cordas que almacenan nos nosos bloques de heap ambos parecían impresos correctamente. 133 00:06:47,000 --> 00:06:49,000 Nada parece mal en todo. 134 00:06:49,000 --> 00:06:52,000 Con todo, imos voltar para o noso código e 135 00:06:52,000 --> 00:06:55,000 Comentar a liña onde copiar CS50 rochas 136 00:06:55,000 --> 00:06:59,000 no bloque de memoria en segundo lugar, apuntada por t. 137 00:06:59,000 --> 00:07:02,000 Agora, cando executar este código que debe 138 00:07:02,000 --> 00:07:06,000 só ver o contido do primeiro bloque de memoria imprimir. 139 00:07:06,000 --> 00:07:09,000 Whoa, aínda que non fixo copias str 140 00:07:09,000 --> 00:07:12,000 os caracteres no bloque heap segundo, aquel apuntado por T, 141 00:07:12,000 --> 00:07:15,000 temos unha impresión. 142 00:07:15,000 --> 00:07:18,000 De feito, a secuencia de nós recheo no noso primeiro bloque 143 00:07:18,000 --> 00:07:21,000 invadiron o primeiro bloque e para dentro do segundo bloque, 144 00:07:21,000 --> 00:07:23,000 facendo que todo pareza normal. 145 00:07:23,000 --> 00:07:26,000 Valgrind, porén, di-nos a historia verdadeira. 146 00:07:26,000 --> 00:07:28,000 Alí imos nós. 147 00:07:28,000 --> 00:07:32,000 Todos aqueles válido le e escribe. 148 00:07:32,000 --> 00:07:36,000 >> Vexamos un exemplo doutro tipo de erro. 149 00:07:36,000 --> 00:07:39,000 Aquí facemos algo bastante infeliz. 150 00:07:39,000 --> 00:07:41,000 Nós coller espazo para un int na pila, 151 00:07:41,000 --> 00:07:45,000 e arrincar un punteiro int - p - para apuntar a este espazo. 152 00:07:45,000 --> 00:07:48,000 Con todo, mentres o noso punteiro é inicializar, 153 00:07:48,000 --> 00:07:52,000 os datos que está a apuntar cara o que acaba de lixo é en que parte do conxunto. 154 00:07:52,000 --> 00:07:55,000 Entón, cando temos de cargar eses datos int i, 155 00:07:55,000 --> 00:07:57,000 que tecnicamente arrincar i, 156 00:07:57,000 --> 00:08:00,000 pero facelo con datos de lixo. 157 00:08:00,000 --> 00:08:03,000 A chamada para afirmar que é unha macro de depuración útil 158 00:08:03,000 --> 00:08:06,000 definido no apropiadamente chamado biblioteca afirmar, 159 00:08:06,000 --> 00:08:09,000 ha abortar o programa a súa condición de proba falla. 160 00:08:09,000 --> 00:08:11,000 É dicir, se eu non for 0. 161 00:08:11,000 --> 00:08:14,000 Dependendo do que foi no espazo de pila, apuntado por p, 162 00:08:14,000 --> 00:08:18,000 este programa pode funcionar algunhas veces e non noutros momentos. 163 00:08:18,000 --> 00:08:20,000 Se funciona, nós estamos só comezando sorte. 164 00:08:20,000 --> 00:08:24,000 O compilador non vai pegar ese erro, pero Valgrind vontade seguro. 165 00:08:24,000 --> 00:08:28,000 Hai que ver o erro que proviña do noso uso destes datos chatarra. 166 00:08:28,000 --> 00:08:32,000 >> Cando aloca memoria heap, pero non desalocar-lo ou libertá-lo, 167 00:08:32,000 --> 00:08:34,000 que se denomina unha fuga. 168 00:08:34,000 --> 00:08:37,000 Para un pequeno programa de curta duración que corre e sae inmediatamente, 169 00:08:37,000 --> 00:08:39,000 vazamentos son bastante inofensivo, 170 00:08:39,000 --> 00:08:42,000 pero para un proxecto de maior porte e / ou lonxevidade, 171 00:08:42,000 --> 00:08:46,000 incluso un pequeno escape pode agravar en algo máis grande. 172 00:08:46,000 --> 00:08:49,000 Para CS50, esperamos que 173 00:08:49,000 --> 00:08:51,000 coidar de liberar toda a memoria heap que reservar, 174 00:08:51,000 --> 00:08:54,000 dende que queremos que constrúe as habilidades para manexar adecuadamente o proceso manual 175 00:08:54,000 --> 00:08:56,000 esixida pola C. 176 00:08:56,000 --> 00:08:59,000 Para iso, o programa debe ter unha exacta 177 00:08:59,000 --> 00:09:03,000 un-para-un entre malloc e chamadas gratuítas. 178 00:09:03,000 --> 00:09:06,000 Afortunadamente, Valgrind pode axudar con vazamentos de memoria tamén. 179 00:09:06,000 --> 00:09:09,000 Aquí está o programa oco chamado leak.c que aloca 180 00:09:09,000 --> 00:09:13,000 espazo na pila, escribe para el, pero non libertá-lo. 181 00:09:13,000 --> 00:09:16,000 Nós compilar con Facer e executa-lo en Valgrind, 182 00:09:16,000 --> 00:09:18,000 e vemos que, mentres temos ningún erro de memoria, 183 00:09:18,000 --> 00:09:20,000 temos un escape. 184 00:09:20,000 --> 00:09:23,000 Hai 16 bytes definitivamente perdidos, 185 00:09:23,000 --> 00:09:27,000 o que significa que o punteiro para que a memoria non estaba no ámbito cando o programa foi encerrado. 186 00:09:27,000 --> 00:09:30,000 Agora, Valgrind non nos dá unha tonelada de información sobre o baleirado, 187 00:09:30,000 --> 00:09:35,000 pero se seguimos esa pequena nota que dá cara ao fondo do seu informe 188 00:09:35,000 --> 00:09:38,000 executar de novo con - Leak-check = total 189 00:09:38,000 --> 00:09:41,000 Para ver os detalles completos de memoria baleirada, 190 00:09:41,000 --> 00:09:44,000 imos obter máis información. 191 00:09:44,000 --> 00:09:46,000 Agora, no resumo heap, 192 00:09:46,000 --> 00:09:50,000 Valgrind dinos onde a memoria que se perdeu foi inicialmente asignado. 193 00:09:50,000 --> 00:09:52,000 Así como sabemos mirar no código fonte, 194 00:09:52,000 --> 00:09:55,000 Valgrind nos informa que filtrou a memoria 195 00:09:55,000 --> 00:09:58,000 alocada cunha chamada a malloc en liña 8 da leak.c 196 00:09:58,000 --> 00:10:00,000 na función principal. 197 00:10:00,000 --> 00:10:02,000 Moi 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 é memoria alocada pila 200 00:10:07,000 --> 00:10:10,000 para que o programa non ten un punteiro. 201 00:10:10,000 --> 00:10:14,000 Valgrind sabe que xa tivo o punteiro, pero, dende entón, perdeu a noción do mesmo. 202 00:10:14,000 --> 00:10:17,000 Esta memoria é sempre filtrou. 203 00:10:17,000 --> 00:10:20,000 Indirectamente perdido - isto é memoria alocada pila 204 00:10:20,000 --> 00:10:24,000 a que só os enlaces para iso tamén se perde. 205 00:10:24,000 --> 00:10:27,000 Por exemplo, se perdeu o punteiro para o primeiro nodo da lista ligada, 206 00:10:27,000 --> 00:10:30,000 a continuación, o primeiro en si sería definitivamente perdidas, 207 00:10:30,000 --> 00:10:34,000 mentres todos os nós posteriores serían indirectamente perdido. 208 00:10:34,000 --> 00:10:37,000 Posiblemente perdeu - esta é a memoria alocada pila 209 00:10:37,000 --> 00:10:41,000 ao cal Valgrind non pode estar seguro se existe un punteiro ou non. 210 00:10:41,000 --> 00:10:44,000 Aínda accesible é a memoria alocada pila 211 00:10:44,000 --> 00:10:47,000 en que o programa ten aínda un punteiro na saída, 212 00:10:47,000 --> 00:10:50,000 o que normalmente significa que unha variable global puntos para el. 213 00:10:50,000 --> 00:10:53,000 Para comprobar estes vazamentos, tamén ten que incluir a opción 214 00:10:53,000 --> 00:10:55,000 - Aínda alcançável = yes 215 00:10:55,000 --> 00:10:58,000 na súa invocación de Valgrind. 216 00:10:58,000 --> 00:11:01,000 >> Estes casos poden requirir diferentes estratexias diferentes para limpa-las para arriba, 217 00:11:01,000 --> 00:11:05,000 pero derrames deben ser eliminados. 218 00:11:05,000 --> 00:11:08,000 Desafortunadamente, fixar vazamentos pode ser difícil de facer, 219 00:11:08,000 --> 00:11:11,000 xa que as chamadas incorrectas libre pode explotar 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 un exemplo de desalocação de memoria malo. 222 00:11:18,000 --> 00:11:21,000 O que debería ser unha soa chamada para liberar todo o bloque 223 00:11:21,000 --> 00:11:24,000 de memoria apuntada por int_block, 224 00:11:24,000 --> 00:11:27,000 en vez diso facer un intento de liberar cada sección int porte 225 00:11:27,000 --> 00:11:29,000 da memoria individual. 226 00:11:29,000 --> 00:11:32,000 Isto ha falla desastrosamente. 227 00:11:32,000 --> 00:11:34,000 Boom! O que un erro. 228 00:11:34,000 --> 00:11:36,000 Isto definitivamente non é bo. 229 00:11:36,000 --> 00:11:39,000 Se está preso con ese tipo de erro, aínda que, e non sabe onde mirar, 230 00:11:39,000 --> 00:11:41,000 caer cara atrás no seu novo mellor amigo. 231 00:11:41,000 --> 00:11:44,000 Vostede difícil de adiviñar - Valgrind. 232 00:11:44,000 --> 00:11:47,000 Valgrind, como sempre, sabe exactamente o que está a suceder. 233 00:11:47,000 --> 00:11:50,000 As contas alloc e libre non combinan. 234 00:11:50,000 --> 00:11:52,000 Temos un alloc e 4 libera. 235 00:11:52,000 --> 00:11:55,000 E Valgrind tamén nos di que a chamada mala primeira libre - 236 00:11:55,000 --> 00:11:58,000 o que desencadeou a Blowup - está a benvida - 237 00:11:58,000 --> 00:12:00,000 liña 16. 238 00:12:00,000 --> 00:12:03,000 Como podes ver, as chamadas para liberar malos son moi malos, 239 00:12:03,000 --> 00:12:05,000 por iso recomendamos deixar o seu programa de escape 240 00:12:05,000 --> 00:12:08,000 mentres se está a traballar para lograr a funcionalidade correcta. 241 00:12:08,000 --> 00:12:12,000 Comezar a buscar vazamentos soamente despois o programa está funcionando correctamente, 242 00:12:12,000 --> 00:12:14,000 sen outros erros. 243 00:12:14,000 --> 00:12:16,000 >> E iso é todo o que temos para este vídeo. 244 00:12:16,000 --> 00:12:18,000 Agora, o que estás esperando? 245 00:12:18,000 --> 00:12:21,000 Ir executar Valgrind nos seus programas agora. 246 00:12:21,000 --> 00:12:25,000 O meu nome é Nate Hardison. Este é CS50. [CS50.TV]