Cat.cpp
И не хочется чтоб это растягивалось на 5 лет, но и ошибаться в каждом втором слове тоже
Cat.cpp
Ок 👌
Vladislav
Я не пойму, или я невнимательный или как? ну как? Почему выводится мусор? Если в отладчике - возвращается верное значение. 1 #include <stdio.h> 2 #include <string.h> 3 4 char* highestScoringWord(const char *str); 5 int size_word(const char* word); 6 7 int main() 8 { 9 printf("%s\n", highestScoringWord("aaa asa aza zzz")); 10 11 return 0; 12 } 13 14 char* highestScoringWord(const char *str) 15 { 16 int max = 0, tmp = 0; 17 char *mword; 18 19 char sent[256]; 20 strcpy(sent, str); 21 char* token = strtok(sent, " "); 22 23 while (token != NULL) 24 { 25 tmp = size_word(token); 26 if (tmp > max) 27 { 28 max = tmp; 29 mword = token; 30 } 31 token = strtok(NULL, " "); 32 } 33 34 return mword; 35 } 36 37 int size_word(const char* word) 38 { 39 int sum = 0; 40 do sum += *word; while (*++word); 41 42 return sum; 43 }
Andrii
И он тебе скажет, где что-то пошло не так
Vladislav
да, теперь даже не компилится. Значит какая-то фигня у меня
Vladislav
что за __asan_... ? он мне его везде пишет
Vladislav
а что она должна делать?
возвращать самое тяжелое слово
sirius
пишите на си ?
sirius
или плюсах
Vladislav
Vladislav
на Си
Vladislav
Либа такая
аа, вот она у меня не найдена. Но я сомневаюсь, что это влияет на мусор в выводе
sirius
есть подозрение что при выходе из ф-ции highestScoringWord память под буфер уничтожается и указатель указывает на мусор
sirius
попробуйте буфер создавать в main
sirius
и передавать как параметр
Vladislav
я правда не понел что это
sirius
char sent[256]; вот этот буфер
Andrii
gcc -O0 -ggdb -fsanitize=address test-sanitizer.c
Andrii
аа, вот она у меня не найдена. Но я сомневаюсь, что это влияет на мусор в выводе
Это не влияет на мусор, у тебя программа упадёт на первой неправильной операции с указателями
Andrii
Скопируй сюда сообщение, или забей в гугле
Vladislav
gcc -O0 -ggdb -fsanitize=address test-sanitizer.c
оно ничего не выводит
sirius
char sent[256]; вот этот буфер
типа вот так: int main() { char sent[256]; printf("%s\n", highestScoringWord("aaa asa aza zzz", sent)); return 0; } char* highestScoringWord(const char* str, char* sent) { int max = 0, tmp = 0; char* mword = nullptr; //char sent[256]; strcpy(sent, str); char* token = strtok(sent, " "); while (token != NULL) { tmp = size_word(token); if (tmp > max) { max = tmp; mword = token; } token = strtok(NULL, " "); } return mword; }
Andrii
оно ничего не выводит
Отлично, тогда запускай ./a.out
Vladislav
что не пропустит?
ну, мне нельзя добавлять аргументы в функцию
sirius
тогда выделяйте память на куче а не на стеке. у вас затирается память при выходе из ф-ции, которая хранит ваше длинное слово в буфере char sent[256];
Andrii
static char sent[256]
Andrii
я не знаю что такое куча, поэтому...
Ндао изучить, без этого сложно...
Vladislav
static char sent[256]
работает
sirius
static char sent[256]
+1 можно статиком, можно вынести из функии в общую память, можно создать память на куче - посмотрите как работает функция malloc и для чего она нужна
Vladislav
Ндао изучить, без этого сложно...
хорошо, так и вписывать: что такое куча?
Vladislav
спасибо опять всем
Vladislav
static char sent[256]
а почему так оно работает?
sirius
а почему так оно работает?
потому что переменная создается не на стеке
sirius
а в постоянной памяти программы, которая затирается и возвращается ос при завершении программы, а не после выхода из функции
Vladislav
ааааа
Andrii
а почему так оно работает?
Потому что есть статическая память, куча и стек. Всё что в стеке, то может быть повреждено при вызове
Andrii
Вс'ё что статическое, создаётся один раз при старте программы, и уничтожается одина раз после выхода
Andrii
А всё что в куче — ты сам контролируешь, когда создать, когда удалить
Vladislav
много мне еще всего нада😁👍
Vladislav
а это нормальные параметры сборки? Или что-то лучше изменить? -O0 -g3 -Wall -c -lm main.c
Andrii
Ещё так можно: $ gcc -O0 -ggdb tm-test.c $ valgrind ./a.out ==26822== Memcheck, a memory error detector ==26822== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==26822== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==26822== Command: ./a.out ==26822== ==26822== Invalid read of size 1 ==26822== at 0x4C34D32: __strlen_sse2 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==26822== by 0x4EBEAB1: puts (ioputs.c:35) ==26822== by 0x108751: main (tm-test.c:9) ==26822== Address 0x1ffefffb8c is on thread 1's stack ==26822== 220 bytes below stack pointer
Alexander
@juliasva https://pikabu.ru/story/kindzadza_vs_dyuna_2021_8520439
Andrii
valgrind ещё такие ошибки ловит
Vladislav
А -lm зачем?
хз, просто где-то увидел
Andrii
хз, просто где-то увидел
Ты линкуешь либу m math скорее всего, но нигде её не юзаешь
Vladislav
valgrind ещё такие ошибки ловит
а его тоже под флагом писать? типо так: -valgrind
Andrii
Я так запускаю gcc -Wall -O0 -ggdb -fsanitize=address tm-test.c А если нужен valgrind, то gcc -Wall -O0 -ggdb tm-test.c
Andrii
Ну можно -ggdb3
Andrii
-Wall выдавать все предупреждения
Andrii
-O0 не оптимизировать
Andrii
-ggdb3 включить отладочную информацию в формате GDB
Andrii
-fsanitize=address проверять работу с указателеми во время выполнения через либу asan
Andrii
valgrind программа, которая чекает ошибки при работе с памятью
Andrii
valgrind и санитайзер лучше не спаривать
Борисов
https://habr.com/ru/post/490850/
Vladislav
Ух щас всего накидаю
Andrii
а это что
-Werror считать ворнинг ошибкой... Ну так...По разному бывает. В целом я не игнорю ворнинги, а прерывать из-за этого билд, такое... -Wextra ну... там ещё параноидальные есть уровень.
Vladislav
теперь у меня ничего не компилится) Класс
Igor
Так и не понял что Слава учит уже неск месяцев и до сих пор не отличает указатель от значения %)
Igor
разберись с типами
Слава, тебе тот же совет)
Борисов
-Werror считать ворнинг ошибкой... Ну так...По разному бывает. В целом я не игнорю ворнинги, а прерывать из-за этого билд, такое... -Wextra ну... там ещё параноидальные есть уровень.
-Werror - в больших проектах да, может быть неудобно - библиотеки чужие используются, хитрые хаки в коде и пр. Но, как показывает практика, единственная гарантия того, что warning исправят - это отсутствие сборки :)
Vladislav
Слава, тебе тот же совет)
Я разбераюсь, только по другому