Грешки на Valgrind

Имам проблем с дешифрирането на изхода на Valgrind, който получавам. Например имам грешка, която казва, че правя незаконен запис на размер 1. Така че добавих един към malloc и това не променя нищо. Тъй като никога преди не съм използвал Valgrind, реших, че ще е най-добре да получа малко помощ, след като търсенето онлайн не даде отговор. Моля, имайте предвид, че не търся отговора, така че не съм възпроизвел кода си. Бих искал да бъда тласнат в правилната посока, за да мога да се боря с бъдещи грешки. Благодаря!

==28881== Memcheck, a memory error detector
==28881== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==28881== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==28881== Command: ./sws root
==28881==
==28892== Conditional jump or move depends on uninitialised value(s)
==28892==    at 0x4C286D9: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x4040B7: get_headers (html.c:280)
==28892==    by 0x402D77: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Conditional jump or move depends on uninitialised value(s)
==28892==    at 0x4C286D9: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x4040C5: get_headers (html.c:280)
==28892==    by 0x402D77: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Conditional jump or move depends on uninitialised value(s)
==28892==    at 0x4C286D9: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x4040D3: get_headers (html.c:280)
==28892==    by 0x402D77: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Conditional jump or move depends on uninitialised value(s)
==28892==    at 0x4C286D9: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x4040E1: get_headers (html.c:280)
==28892==    by 0x402D77: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2874C: strcpy (mc_replace_strmem.c:311)
==28892==    by 0x4041E1: get_headers (html.c:299)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2875F: strcpy (mc_replace_strmem.c:311)
==28892==    by 0x4041E1: get_headers (html.c:299)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be034 is 4 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x4041F7: get_headers (html.c:300)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2838C: strcat (mc_replace_strmem.c:176)
==28892==    by 0x4041F7: get_headers (html.c:300)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be034 is 4 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2839F: strcat (mc_replace_strmem.c:176)
==28892==    by 0x4041F7: get_headers (html.c:300)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be061 is 15 bytes before a block of size 40 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x403E53: get_headers (html.c:224)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x40420D: get_headers (html.c:301)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x40420D: get_headers (html.c:301)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2838C: strcat (mc_replace_strmem.c:176)
==28892==    by 0x40420D: get_headers (html.c:301)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be061 is 15 bytes before a block of size 40 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x403E53: get_headers (html.c:224)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x404223: get_headers (html.c:302)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C28374: strcat (mc_replace_strmem.c:176)
==28892==    by 0x404239: get_headers (html.c:303)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid write of size 1
==28892==    at 0x4C2838C: strcat (mc_replace_strmem.c:176)
==28892==    by 0x404239: get_headers (html.c:303)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be098 is 0 bytes after a block of size 40 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x403E53: get_headers (html.c:224)
==28892==    by 0x402E00: read_page (networking.c:347)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Invalid read of size 1
==28892==    at 0x4C286E4: __GI_strlen (mc_replace_strmem.c:284)
==28892==    by 0x402E0F: read_page (networking.c:348)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892== Syscall param socketcall.sendto(msg) points to unaddressable byte(s)
==28892==    at 0x5121052: send (send.c:28)
==28892==    by 0x40276D: send_msg (networking.c:245)
==28892==    by 0x402E29: read_page (networking.c:348)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==  Address 0x53be030 is 0 bytes after a block of size 32 alloc'd
==28892==    at 0x4C274A8: malloc (vg_replace_malloc.c:236)
==28892==    by 0x402D84: read_page (networking.c:341)
==28892==    by 0x402B8E: get_page (networking.c:310)
==28892==    by 0x40268E: header_parse (networking.c:232)
==28892==    by 0x401D96: retrieve_msg (networking.c:62)
==28892==    by 0x401AAB: main (sws.c:139)
==28892==
==28892==
==28892== HEAP SUMMARY:
==28892==     in use at exit: 337 bytes in 10 blocks
==28892==   total heap usage: 19 allocs, 9 frees, 3,307 bytes allocated
==28892==
==28892== LEAK SUMMARY:
==28892==    definitely lost: 337 bytes in 10 blocks
==28892==    indirectly lost: 0 bytes in 0 blocks
==28892==      possibly lost: 0 bytes in 0 blocks
==28892==    still reachable: 0 bytes in 0 blocks
==28892==         suppressed: 0 bytes in 0 blocks
==28892== Rerun with --leak-check=full to see details of leaked memory
==28892==
==28892== For counts of detected and suppressed errors, rerun with: -v
==28892== Use --track-origins=yes to see where uninitialised values come from
==28892== ERROR SUMMARY: 348 errors from 17 contexts (suppressed: 4 from 4)
==28881==
==28881== HEAP SUMMARY:
==28881==     in use at exit: 0 bytes in 0 blocks
==28881==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==28881==
==28881== All heap blocks were freed -- no leaks are possible
==28881==
==28881== For counts of detected and suppressed errors, rerun with: -v
==28881== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

217 int get_headers(char* time, char* last_modified, char* server, char* content_type, size_t msglen, char* header, int flag)
218 {
219         char* header1 = NULL;
220         char* header2 = NULL;
221         char* header3 = NULL;
222         char* header4 = NULL;
223         char* header5 = NULL;
224
225         if ((header1 = (char*)malloc(strlen("Date: ")+strlen(time)+2) ) ==NULL)
226         {
227                 fprintf(stderr, "%s: No more memory\n", getprogname());
228                 exit(EXIT_FAILURE);
229         }
230
231
232         strcpy(header1, "Date: ");
233         strcat(header1, time);
234         strcat(header1, "\n");
235
236
237         if ((header2 = (char*)malloc(strlen("Last-Modified: ")+strlen(last_modified)+5) ) ==NULL)
238         {
239                 fprintf(stderr, "%s: No more memory\n", getprogname());
240                 exit(EXIT_FAILURE);
241         }
242
243
244         strcpy(header2, "Last-Modified: ");
245         strcat(header2, last_modified);
246         strcat(header2, "\n");
247
248
249         if ((header3 = (char*)malloc(strlen("Server: ")+strlen(server)+5) ) ==NULL)
250         {
251                 fprintf(stderr, "%s: No more memory\n", getprogname());
252                 exit(EXIT_FAILURE);
253         }
254
255
256         strcpy(header3, "Server: ");
257         strcat(header3, server);
258         strcat(header3, "\n");
259
260
261         if ((header4 = (char*)malloc(strlen("Content-Type: ")+strlen(content_type)+5) ) ==NULL)
262         {
263                 fprintf(stderr, "%s: No more memory\n", getprogname());
264                 exit(EXIT_FAILURE);
265         }
266
267
268         strcpy(header4, "Content-Type: ");
269         strcat(header4, content_type);
270         strcat(header4, "\n");
271
272
273         int content_length = strlen(header1)+strlen(header2)+strlen(header3)+strlen(header4)+strlen("Content-Length: ")+msglen+5;
274         char temp[10] = {' '};
275         snprintf(temp, sizeof(msglen),"%d", content_length);
276
277         if ((header5 = (char*)malloc(strlen("Content-Length: ")+strlen(temp)+5) ) ==NULL)
278         {
279                 fprintf(stderr, "%s: No more memory\n", getprogname());
280                 exit(EXIT_FAILURE);
281         }
282
283
284         strcpy(header5, "Content-Length: ");
285         strncat(header5, temp, strlen(temp));
286         strcat(header5, "\n\n");
287
288
289         if(flag == 1)
290         {
291                 strcpy(header, header1);
292                 strcat(header, header2);
293                 strcat(header, header3);
294                 strcat(header, header4);
295                 strcat(header, header5);
296         }
297
298         return content_length;
299         free(header1);
300         free(header2);
301         free(header3);
302         free(header4);
303         free(header5);
304 }

person tpar44    schedule 07.11.2012    source източник
comment
Виждането на съответните кодови местоположения би било полезно за обяснение на тези съобщения.   -  person BjoernD    schedule 08.11.2012
comment
@BjoernD Добавих функцията (с относителни номера на редове), която има проблеми с valgrind   -  person tpar44    schedule 08.11.2012
comment
Възможно ли е flag да е невярно? В този случай вие не поставяте никакви данни в header1, header2 и т.н., но все още извиквате strlen с тях (неинициализирано).   -  person Omri Barel    schedule 08.11.2012
comment
strcat(header1, "\0"); - това е просто глупаво. не прави нищо.   -  person Karoly Horvath    schedule 08.11.2012
comment
и какъв е смисълът от тези mallocs? можете да пишете директно на header.   -  person Karoly Horvath    schedule 08.11.2012
comment
@KarolyHorvath Не мога да пиша директно в заглавката, защото не искам да имам буфер с фиксиран размер за съхраняване на заглавката, защото не знам размера, който ще бъде заглавката, преди да вляза в тази функция.   -  person tpar44    schedule 08.11.2012
comment
@tpar44: ?? предавате указателя на заглавката и пишете в него в тази функция...   -  person Karoly Horvath    schedule 08.11.2012
comment
@KarolyHorvath Извиквам тази функция два пъти. Веднъж, за да получа размера на заглавката, след това i Malloc пренастроения размер и го извиквам отново този път, добавяйки неща към показалеца на заглавката   -  person tpar44    schedule 08.11.2012
comment
добре, сега има смисъл, тъй като актуализирахте въпроса си...   -  person Karoly Horvath    schedule 08.11.2012


Отговори (3)


Ако flag е 0, тогава никога не инициализирате никакви данни в низовете header1..4, така че когато се опитате да получите техните дължини с strlen, вие четете неинициализиран боклук. Трябва да се уверите, че винаги инициализирате стойностите на заглавките към празни низове, независимо от настройката flag.

Също така, няма нужда да strcat(..., "\0") върху низа -- strcpy и strcat винаги завършват с нула низовете (всъщност "\0" е неразличим от празния низ "", тъй като и двата им първи байта са байт NUL). И се пазете от алгоритмите на Shlemiel the Painter, когато свързвате куп низове заедно.

person Adam Rosenfield    schedule 07.11.2012
comment
Въз основа на + 5 на OP за malloc, имам силно подозрение, че той наистина е искал да напише strcat(..., "\\n\\0");. Бих използвал sprintf или нещо подобно. - person Happy Green Kid Naps; 08.11.2012
comment
не, не това имаше предвид. той генерира заглавка на HTTP отговор - person Karoly Horvath; 08.11.2012

1) Освободихте 5 части памет и не ги освободихте във вашата функция. Те трябва да бъдат освободени, преди да се върнете или да излезете. Забележете как valgrind казва, че имате 326 байта, които са били definitely lost.

2) Ако flag е false, вашите header* променливи никога не се настройват на нищо, поради което valgrind ви дава куп грешки на ред 280. Впоследствие няма нищо добро за копиране по-късно около ред 301, така че получавате повече грешки .

person GraphicsMuncher    schedule 07.11.2012

Тъй като се интересувате от писането на „чист + готин“ код, ще се опитам да ви насоча в правилната посока. Най-добрият начин за борба с бъдещите грешки е да бъдете прости.

Какво е просто? Направете го във възможно най-малко редове, но все пак го поддържайте четлив и лесен за разбиране. Вместо 87 реда (304-217) код, можете да го направите в 30 реда.

Освен това е добра нагласа да търсите места, където кодът може да влезе в „недефинирано“ поведение. Би било добра практика да включите размера на заглавката в get_header(). Ако не е наличен в get_header(), тогава няма начин да се предотврати потенциално препълване на буфера/повреда на паметта.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
get_header(char *date, char *last_m, char *server, char *c_type,
        int c_len, char *header, int flag, int h_len);

int
main()
{
        char header[500];
        int n;

        n = get_header(
                "Fri, 09 Nov 2012 09:22:06 GMT", /* Date            */
                "Fri, 09 Nov 2012 09:10:32 GMT", /* Last modified   */
                "MySuperDuperServer/V 1.0.0.0",  /* Server name     */
                "Text/html",                     /* Content type    */
                1234,                            /* Content length  */
                header,                          /* Destination buf */
                1,             /* 1 = write into header, 0 = Do not */
                sizeof(header)                   /* header buf size */
        );             

        printf("%s\n", header);

        exit(0);
}

/* Header lines should end with CR LF */

#define DATE   "Date: %s\r\n"
#define LAST_M "Last-Modified: %s\r\n"
#define SERVER "Server : %s\r\n"
#define C_TYPE "Content-Type: %s\r\n"
#define C_LEN  "Content-Length: %d\r\n\r\n"

#define HEADER DATE LAST_M SERVER C_TYPE C_LEN

int
get_header(char *date, char *last_m, char *server, char *c_type,
        int c_len, char *header, int flag, int h_len)
{
        char *d;
        int r;

        if (flag == 1) {
                d = header;
        }
        else if ((d = (char *)malloc(h_len)) == 0) {
                printf("out of memory\n");
                exit(1); /* exit(EXIT_FAILURE); */
        }

        r = snprintf(d, h_len, HEADER, date, last_m, server, c_type, c_len);

        if (flag == 0) {
                free(d);
        }

        return(r);
}

Надявам се да намерите това за полезно.

person Arun Taylor    schedule 10.11.2012