static button s1;
в заголовочном файле, а это значит, что каждая единица трансляции в которую ты подключил этот файл получит свой собственный, независимый экземпляр переменной s1. Функция ModesInit
инициализирует s1 из ModeDriver.o
, а s1 из main.o
останется неинициализированным.static
на extern
в заголовочном файле, а в одном из исходников добавив определение для переменной -- button s1;
. sizeof(dict)/sizeof(const char)
const char
а не на размер const char *
. Во избежание таких ошибок для вычисления размера массива обычно пишут sizeof(dict)/sizeof(dict[0])
. можно подумать, что при объявлении указателя, символ * относится к имени(не как часть, а как что-то зависящее от него), а не к типу.
const char *a, b;
можно превратить в const char (*a), b
, но нельзя превратить в const (char *a), b
или в char (const *a), b
.Компилирую gcc -o outfile source.c -lpthread. То есть собираю без всяких статиков, чтобы были зависимости к подключенным библиотекам. Далее запускаю процесс, чекаю /proc/pid/maps. Там нет ни единого упоминания к libpthread.
-lpthread
продолжали собираться, внутри пустая. Короче, ты выбрал неудачного кандидата для экспериментов. Почему в Си после main() не ставят ;?
;
между объявлением и телом функции, не только для main
, но и для любой другой функции. Согласно стандарту языка, например С99 приводит следующий синтаксис определения функции:function-definition:
declaration-specifiers declarator declaration-list<opt> compound-statement
declaration-list:
declaration
declaration-list declaration
extern int max(a, b)
int a, b;
{
return a > b ? a : b;
}
;
.эта строка работает на другом языке?
Соответственно, мне нужно конвертировать массив wchar_t в массив char перед шифрованием, а после дешифровки выполнять обратную конвертацию.
Я поменял сигнатуру функции main() на int main(int argc, wchar_t* argv[]) (пытался исправлять на wmain, но тогда ругается ld и сборка падает с ошибкой).
int main(void)
, int main(int argc, char *argv[])
или эквивалентным. Там же написано, что набор символов во время выполнения программы -- implementation defined, поэтому нет гарантии, что их можно обработать кросплатформенно.Для конвертации wchar_t* в char* я пробовал использовать функцию wcstombs, однако почему-то у меня она совершенно не работает (при попытке преобразовать строку, содержащую только латиницу, я получаю null).
wcstombs
не занимается выделением памяти, если ты "получаешь null" -- это происходит в каком-то другом месте. Ну и если ты это делаешь внутри main принимающего wchar_t* argv[]
, то твой код интерпретирует строку char
как строку wchar_t
, что добавляет хаоса. Но в режиме отладки всё, как я уже писал выше, работает.
$ gcc -std=c99 -O2 -g3 -fsanitize=address main.c acp.c md5.c -o main
$ ./main
Base64('Hello') = "SGVsbG8="
MD5('Hello') = "8b1a9953c4611296a827abf8c47804d7"
=================================================================
==1045705==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000000071 at pc 0x7fb0d46486f8 bp 0x7ffd0affb580 sp 0x7ffd0affad30
WRITE of size 33 at 0x604000000071 thread T0
#0 0x7fb0d46486f7 in __interceptor_strcat ../../../../src/libsanitizer/asan/asan_interceptors.cpp:377
#1 0x564b2388c0de in prepareKeys /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:263
#2 0x564b2388cac4 in acraw /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:319
#3 0x564b2388d8c2 in acraws /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:401
#4 0x564b2388d8c2 in acraws_basic /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/acp.c:409
#5 0x564b2388a62e in testSimpleEncryption /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/main.c:20
#6 0x564b2388a368 in main /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/main.c:111
#7 0x7fb0d44461c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#8 0x7fb0d4446284 in __libc_start_main_impl ../csu/libc-start.c:360
#9 0x564b2388a440 in _start (/home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/main+0x3440)
0x604000000071 is located 0 bytes to the right of 33-byte region [0x604000000050,0x604000000071)
allocated by thread T0 here:
#0 0x7fb0d46b89cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69
#1 0x564b2388fee7 in md5StringHash /home/jcmvbkbc/tmp/toster/1331202/alphacrypt2/md5.c:227
Может ли язык Си работать на условной стековой машине? … В виде стековой машины я имею в виду условную машину Тьюринга
Будут ли какие-то проблемы для генерации кода из Си в ассемблер для подобной машины?
Почему ls не работает
./main `pwd`/mntpoint
) -- то становится лучше. Но всё ещё не работает, потому что при использовании обработчиком запроса на доступ к каталогу этого же самого каталога происходит бесконечная рекурсия и исходный запрос не завершается.Есть, может, какие-то специальные книги по этой теме?
#define BIT_SET(port, bit) (port |= (1 << bit)) int main(void) { BIT_SET(PORTB, PORTB0); }
вот такой вариант, с макро-функцией, работает, так как это просто текстовая замена
0x04 |= 1 << 0
не имеет смысла. Он определён как volatile ссылка на память с адресом 0x04. Когда ты научишься передавать ссылку на такую память в функцию, функция тоже начнёт работать. Пытаюсь поставить библиотеку, не получается
почему?
file INSTALL cannot find "/home/durachok/HTTPParser/build/_deps/ethernet-src/include/Ethernet.h": No such file or directory.
почему не работает USER тред?
makecontext
не задав uc_link
. thread_func1
отрабатывает, а дальше гонка между вызовом thread_func2
из monitor_thread
и завершением программы из-за возврата из функции контекста в контексте созданном с uc_link == NULL
.clone
. Непонятно зачем дублировать указатель на функцию в Thread::func
и в Thread::context
. Непонятно зачем контексты, если schedule
их не использует. Непонятно, зачем monitor_thread
занимается активным ожиданием Thread::active
. Непонятно, зачем функции потоков лезут в потроха Thread
. Короче, этому коду не хватает идеи. Почему не печатается "custom thread completed"
thread->context.uc_link = NULL;
в строке 27, а, согласно man swapcontext: If the successor context pointer is NULL, the thread exits.
int custom_thread_create(custom_thread *thread, ucontext_t *link, void (*start_routine)(void*), void *arg) {
…
thread->context.uc_link = link;
…
}
…
ucontext_t main_context;
getcontext(&main_context);
if (custom_thread_create(&thread, &main_context, print_message, (void*)message) == 0) {
…
Хочется как-то отойти от указания всех параметров а считать что есть некий контекст.