Opened 5 years ago

Closed 4 years ago

#441 closed ожидается проверка (задача сдана)

WW#5

Reported by: berbat.georgiy Owned by: Артур Гулецкий (huletski)
Component: WW_c_io Version: 2.0
Keywords: Cc:

Description

Очень-очень-очень сырая версия. Но хотя бы что-то. Промежуточный дедлайн же сегодня?

Change History (3)

comment:1 Changed 5 years ago by Артур Гулецкий (huletski)

Type: ожидается проверкаожидаются исправления

Промежуточный дедлайн же сегодня?

Скорее финальный. Дедлайн был продлен до 10.10 23:59.

Решение не собирается:

{lab_05}[2047]$ pwd && svn up && svn status
/home/hfx/dvl/cpp19/berbat.georgiy/lab_05
Updating '.':
At revision 1741.
{lab_05}[2048]$ make
mkdir obj
gcc -c src/clist.c -Iinclude -Wall -Wextra -Werror -o obj/clist.o
gcc -c src/point_list.c -Iinclude -Wall -Wextra -Werror -o obj/point_list.o
gcc -c -Iinclude -Wall -Wextra -Werror src/main.c -o obj/main.o
src/main.c: In function ‘op’:
src/main.c:10:25: error: implicit declaration of function ‘get_point’; did you mean ‘add_point’? [-Werror=implicit-function-declaration]
   10 |     point_node *pnode = get_point(node);
      |                         ^~~~~~~~~
      |                         add_point
src/main.c:10:25: error: initialization of ‘point_node *’ {aka ‘struct point_node *’} from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion]
src/main.c: In function ‘main’:
src/main.c:27:13: error: implicit declaration of function ‘assert’ [-Werror=implicit-function-declaration]
   27 |             assert(in_f);
      |             ^~~~~~
src/main.c:5:1: note: ‘assert’ is defined in header ‘<assert.h>’; did you forget to ‘#include <assert.h>’?
    4 | #include <stdlib.h>
  +++ |+#include <assert.h>
    5 | 
src/main.c:25:19: error: variable ‘read_str’ set but not used [-Werror=unused-but-set-variable]
   25 |             char* read_str;
      |                   ^~~~~~~~
src/main.c:52:22: error: multi-character character constant [-Werror=multichar]
   52 |             char* p2['smth'];
      |                      ^~~~~~
src/main.c:62:37: error: initialization of ‘point_node *’ {aka ‘struct point_node *’} from ‘int’ makes pointer from integer without a cast [-Werror=int-conversion]
   62 |                 point_node *pnode = get_point(node);
      |                                     ^~~~~~~~~
src/main.c:63:28: error: implicit declaration of function ‘itoa’ [-Werror=implicit-function-declaration]
   63 |                 put_str1 = itoa(pnode->x); //уже знаю, что такой в си нет и придётся, что-то с этим делать
      |                            ^~~~
src/main.c:65:34: error: passing argument 1 of ‘strcat’ makes pointer from integer without a cast [-Werror=int-conversion]
   65 |                 put_str = strcat(put_str1, ' ');
      |                                  ^~~~~~~~
      |                                  |
      |                                  char
In file included from src/main.c:3:
/usr/include/string.h:133:14: note: expected ‘char * restrict’ but argument is of type ‘char’
  133 | extern char *strcat (char *__restrict __dest, const char *__restrict __src)
      |              ^~~~~~
src/main.c:65:44: error: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Werror=int-conversion]
   65 |                 put_str = strcat(put_str1, ' ');
      |                                            ^~~
      |                                            |
      |                                            int
In file included from src/main.c:3:
/usr/include/string.h:133:14: note: expected ‘const char * restrict’ but argument is of type ‘int’
  133 | extern char *strcat (char *__restrict __dest, const char *__restrict __src)
      |              ^~~~~~
src/main.c:66:43: error: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Werror=int-conversion]
   66 |                 put_str = strcat(put_str, put_str2);
      |                                           ^~~~~~~~
      |                                           |
      |                                           char
In file included from src/main.c:3:
/usr/include/string.h:133:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
  133 | extern char *strcat (char *__restrict __dest, const char *__restrict __src)
      |              ^~~~~~
src/main.c:67:43: error: passing argument 2 of ‘strcat’ makes pointer from integer without a cast [-Werror=int-conversion]
   67 |                 put_str = strcat(put_str, '\n');
      |                                           ^~~~
      |                                           |
      |                                           int
In file included from src/main.c:3:
/usr/include/string.h:133:14: note: expected ‘const char * restrict’ but argument is of type ‘int’
  133 | extern char *strcat (char *__restrict __dest, const char *__restrict __src)
      |              ^~~~~~
src/main.c:75:22: error: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Werror=format=]
   75 |             printf("%d", &counter);
      |                     ~^   ~~~~~~~~
      |                      |   |
      |                      int int *
      |                     %ls
src/main.c:30:28: error: ‘str’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   30 |                 read_str = fgets(str, sizeof(str), in_f);
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.c:37:34: error: ‘podstroka_raz’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   37 |                     podstroka_raz[i] = str[i];
      |                                  ^
src/main.c:36:22: error: ‘checker’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   36 |                 while(checker != 32){
      |                      ^
src/main.c:43:34: error: ‘podstroka_dva’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   43 |                     podstroka_dva[i] = str[i];
      |                                  ^
src/main.c:74:13: error: ‘p2’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
   74 |             apply(l, op, p2);
      |             ^~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
Makefile:19: recipe for target 'obj/main.o' failed
make: *** [obj/main.o] Error 1

Пару комментариев по коду:

  • main.c:6. counter не должен быть глобальной переменной, используйте аргумент data (см. след. пункт);
  • main.c:8. data (или p2 как у вас) нужен для того, чтобы была возможность как-то передавать аргументы функции apply и сохранять произвольное промежуточное состояние между вызовами функции-callback'a на элементах списка. Как аргумент будет использоваться, зависит от логики функции-callback'a;
  • main.c:63. Одно из решений: использовать fprintf и ходить на практики/лекции;
  • единый стиль отступов не соблюдается;
  • main.c:32. Использовать транслитерацию для имен переменных - так себе идея -> s/podstroka_raz/first_substring. Ну а вообще, используйте fscanf, чтобы не парсить числа вручную.

--
Итог: 0, время сделать хотя бы часть задания еще есть.

comment:2 Changed 4 years ago by berbat.georgiy

Type: ожидаются исправленияожидается проверка
Version: 1.02.0

Спасибо большое за советы, верное понимание apply() и её аргументов сильно упростило задачу.

comment:3 Changed 4 years ago by Артур Гулецкий (huletski)

Resolution: задача сдана
Status: assignedclosed

Некорректная работа программы на большинстве тестов; есть ошибки при работе с памятью, например:

{lab_05}[2014]$ pwd && svn up && svn status
/home/hfx/dvl/cpp19/berbat.georgiy/lab_05
Updating '.':
At revision 1794.
?       in.txt  
{lab_05}[2015]$ cat in.txt 
1 2
4 3
5 5
{lab_05}[2016]$ make
mkdir obj
gcc -c src/clist.c -Iinclude -Wall -Wextra -Werror -o obj/clist.o
gcc -c src/point_list.c -Iinclude -Wall -Wextra -Werror -o obj/point_list.o
gcc -c -Iinclude -Wall -Wextra -Werror src/main.c -o obj/main.o
gcc obj/clist.o obj/point_list.o obj/main.o -o lab_05
{lab_05}[2017]$ valgrind ./lab_05 loadtext in.txt savetext out.txt
==4214== Memcheck, a memory error detector
==4214== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==4214== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==4214== Command: ./lab_05 loadtext in.txt savetext out.txt
==4214== 
==4214== 
==4214== HEAP SUMMARY:
==4214==     in use at exit: 72 bytes in 3 blocks
==4214==   total heap usage: 7 allocs, 4 frees, 9,368 bytes allocated
==4214== 
==4214== LEAK SUMMARY:
==4214==    definitely lost: 24 bytes in 1 blocks
==4214==    indirectly lost: 48 bytes in 2 blocks
==4214==      possibly lost: 0 bytes in 0 blocks
==4214==    still reachable: 0 bytes in 0 blocks
==4214==         suppressed: 0 bytes in 0 blocks
==4214== Rerun with --leak-check=full to see details of leaked memory
==4214== 
==4214== For counts of detected and suppressed errors, rerun with: -v
==4214== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

Замечания по корректности:

  • ошибки при работе с памятью: не освобождаете память, выделенную для хранения точек -> -1; считывание бинарного файла (пояснение см. ниже) -> -2;
  • вывод текстового файла: неверный формат (point_list.c:92), по условию должен быть "%d %d\n" -> -1;
  • неверно реализована функция чтения бинарного файла: читается лишняя точка (почему полагаться исключительно на feof нельзя рассказывалось на практике) -> -1. Ad-hoc fix:
    // main.c:32
    int read_bytes_nm = fread(x, 1, 1, in_f);
    if (read_bytes_nm != 1) { break; }
    
  • неверно реализована функция сохранения в бинарный файл: вызов функции fwrite(get_x_ad, 3, 1, where_to_save); сохраняет первые три байта кода функции get_x_ad, а не значение координаты точки. Fix: fwrite(get_x_ad(node), 3, 1, where_to_save); -> -1.

Считывание бинарного файла:

  1. main.c:27: выделяется один байт неинициализированной (содержит случайные данные) динамической памяти, на которую будет ссылаться указатель на int (btw sizeof(int) != 1);
  2. main.c:32: чтение из файла одного байта -> первый байт области памяти, на кот. ссылается указатель становится инициализированным;
  3. main.c:33: копирование _sizeof(int)_ байтов в xxx, тогда как инициализирован только младший -> в xxx лежит мусор в старших байтах.
  4. Последующие строки инициализируют второй и третий байт -> четвертый байт значения координаты содержит случайные данные.

Ad-hoc fix: в main.c:27 объявить указатель на char, a не на int.
Fix: читать сразу по три байта int x; read(&x, 3, 1, in_f);


Некоторые замечания по стилю:

  • нарушен единый стиль отступов (main.c, clist.c) -> -1;
  • функции сохранения, печати и прочие, передаваемые в apply, лучше было бы реализовать в main.c, т.к. они специфичны для кода-пользователя списка.

За то, что, похоже, писали сами и разобрались с apply более-менее +1.

Итог: 4.

Note: See TracTickets for help on using tickets.