Пытаюсь выделить память с помощью mmap, вот код:
long long *copy;
copy = (long long*)mmap(NULL,
(size_t)1024,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (copy == MAP_FAILED) {
fprintf(stderr, "Memory allocation failed (Process aborted)\n");
exit(1);
}
printf("Pointer: %p\n", copy);
Очевидно, я проверяю, не происходит ли выделение. Когда это произойдет, я должен получить -1 из того, что я получил из справочные страницы. Дело в том, что я получаю -12, ну 0xfffffffffffffff4
, так что ошибка не ловится и программа продолжается. Я подумал, может быть, это из-за приведения (long long*)
, но приведение не должно изменять значение указателя. Поэтому мне очень любопытно, почему это происходит и как это предотвратить.
Более странное поведение:
Я попытался напечатать файл errno
. Если я использую printf("%d\n", errno);
, он печатает 0, а указатель по-прежнему установлен на 0xfffffffffffffff4
. Но если я использую err(errno, "%p", copy);
, он печатает:
program.exe: 0x7f8130981000: Success
И теперь указатель действителен, но я не могу его использовать, потому что err
завершил выполнение.
program.exe
— вы на Windows? Вы используете MinGW или Cygwin или что-то еще? - person Jonathan Leffler   schedule 20.08.2017mmap
. В C это никогда не требуется и может скрыть ошибки. Может быть, вы забыли#include <stdlib.h>
? Может быть, вы не включили все предупреждения?-Wall
мог бы рассказать вам больше. - person Jens Gustedt   schedule 20.08.2017printf("Pointer: %p\n", (void *)copy)
? (Хорошо: есть половина оправдания, если это сработает, но маловероятно, что это что-то изменит.) - person Jonathan Leffler   schedule 20.08.2017-Wmissing-prototypes -Wstrict-prototypes -Werror -Wextra
так же, как и с-Wall
? Опять же, если вы включили необходимые заголовки, это ничего не изменит — если вы аккуратный программист. Если вы не включили необходимые заголовки или являетесь небрежным программистом, у вас может быть больше работы, чем вы ожидали. (Я использую эти опции все время; у меня нет шанса быть небрежным программистом — по крайней мере, не в том смысле, что я сталкиваюсь с проблемами из-за ошибок, которые выявляют эти опции.) Кроме того, что произойдет, если вместо этого вы используетеwarnc()
изerr()
? - person Jonathan Leffler   schedule 20.08.2017<err.h>
не включен. Когда я включил его, произошло следующее:program.exe: 0xfffffffffffffff4: Success
Значит, неявное объявление err заставило его работать? Также, как предположил Джин, я работаю над MCVE, но, похоже, я не могу воспроизвести это поведение. - person Hadron   schedule 20.08.2017<err.h>
привело к сбою другими, более творческими способами — вы не знаете, был ли напечатанный указательerr()
действительным, потому что программа завершилась. Я не видел поведения, похожего на то, что вы видите (за исключением вашего прото-MCVE), очень часто, особенно когда включены правильные заголовки и объявлены функции. В Linux (и некоторых, возможно, многих других системах) ошибка 12 — это ENOMEM. Есть ли опасность использования забавной функции отображения, которая преобразует код ошибки-1
в-errno
? Становится диковинным… - person Jonathan Leffler   schedule 20.08.2017mmap()
являетсяsys/mman.h
как в соответствии с стандартом POSIX, так и справочная страница Linux. Откудаerr.h
? - person Andrew Henle   schedule 21.08.2017err()
, чтобы узнать, был ли вызовmmap()
успешным. И это соответствуетerrno
, но возвращаемое значение не является допустимым указателем. Все остальные включения были в порядке. - person Hadron   schedule 21.08.2017errno
недоступна, если у вас нет этого оператора:#include <errno.h>
- person user3629249   schedule 21.08.2017gcc -c -ggdb -Wall -Wextra -pedantic -Wconversion -std=gnu11 myprogram.c -o myprogram.o
- person user3629249   schedule 21.08.2017