Модуль Python C – Malloc не работает в конкретной версии Python

Я пишу модуль Python для выполнения ввода-вывода в контексте O_DIRECT. Одно из ограничений O_DIRECT заключается в том, что вы должны читать буфер, выровненный по границе 4096 байт для ядер 2.4 и 2.5, а 2.6 и выше будут принимать любое количество из 512.

Очевидным кандидатом на выделение памяти для этого является posix_memalign(void **memptr, size_t alignment, size_t size)

В моем коде я выделяю такую ​​область:

 char *buffer = NULL; int mem_ret = posix_memalign((void**)&buffer, alignment, size); if (!buffer) { PyErr_NoMemory(); return NULL; } /* I do some stuff here */ free(buffer); 

Когда я компилирую и импортирую модуль с помощью python3.2, этот (и остальная часть не отображаемого модуля) работает нормально.

Когда я пытаюсь сделать то же самое с python2.7 (я хотел бы сохранить совместимость), он выдает исключение mem_ret == ENOMEM и mem_ret == ENOMEM , указывая, что он не смог выделить.

Почему версия Python I компиляции влияет на то, как работает posix_memalign?

ОС: Ubuntu 12.04 LTS

Компилятор: Clang + GCC Показать такое же поведение

ОБНОВИТЬ

У меня теперь есть кусок кода, благодаря user694733
Однако тот факт, что он работает, меня еще больше смущает:

 #if PY_MAJOR_VERSION >= 3 char *buffer = NULL; int mem_ret = posix_memalign((void**)&buffer, alignment, count); #else void *mem = NULL; int mem_ret = posix_memalign(&mem, alignment, count); char *buffer = (char*)mem; #endif 

Может кто-нибудь объяснить, почему неправильный первый блок работает под Python3, но не 2.7, и что еще более важно, почему правильный второй блок не работает под Python3?

ОБНОВЛЕНИЕ 2

Сюжет сгущается, опустившись на правильную форму кода ниже, я протестировал 4-ю версию Python.

 void *mem = NULL; int mem_ret = posix_memalign(&mem, alignment, count); char *buffer = (char*)mem; if (!buffer) { PyErr_NoMemory(); return NULL; } /* Do stuff with buffer */ free(buffer); 

В Python 2.7 : этот код работает, как ожидалось.
В Python 3.1 : этот код работает как ожидалось.
В Python 3.2 : этот код генерирует mem_ret == ENOMEM и возвращает NULL для buffer
В Python 3.3 : этот код работает как ожидалось.

Версии Python, не включенные в репозитории Ubuntu, были установлены из PPA по адресу https://launchpad.net/~fkrull/+archive/deadsnakes

Если верить версиям, помеченным в бинарные файлы Python, версии, которые я установил, следующие:

 python2.7 python3.1 python3.2mu (--with-pymalloc --with-wide-unicode) python3.3m (--with-pymalloc) 

Могла ли использовать флаг широкоформатного unicode в распределении Python3 по умолчанию, чтобы вызвать эту ошибку? Если да, то как это происходит?

Для ясности, отказ ENOMEM для выделения будет происходить с любым вариантом malloc() , даже с чем-то простым, как malloc(512) .

2 Solutions collect form web for “Модуль Python C – Malloc не работает в конкретной версии Python”

Для быстрого обхода придерживайтесь mmap вместо malloc+memalign

posix_memalign не может быть одним и тем же телом кода в одной среде компиляции как другой. Вы легко могли себе представить, что Python 3 будет использовать различные макросы для тестирования функций для Python 2. Это может означать, что он заканчивает работу с другим кодом.

Вы можете взглянуть на символы, которые используются … часто, когда выходные данные ldd или nm будут иметь искаженные имена, которые указывают, какая версия фактически используется.

Кроме того, что делает шоу strace системы распределения? Я считаю, что это хороший способ увидеть, являются ли аргументы неверными, что может стать причиной получения ENOMEM.

  • Строки, на которые не ссылаются dicts?
  • Переопределение поведения генерации новой строки оператора печати Python
  • вы можете восстановить после переназначения __builtins__ в python?
  • deque.popleft () и list.pop (0). Есть ли разница в производительности?
  • Упорядоченные слова
  • Почему эти две функции различны?
  • CPython - интерпретатор байт-кода?
  • При тестировании глубины рекурсии python max, почему я нажимаю RuntimeError несколько раз?
  • Почему я не должен использовать PyPy над CPython, если PyPy в 6,3 раза быстрее?
  • Как я могу управлять модулем / именем класса cythf cython?
  • Почему деструктор называется, когда сборщик мусора CPython отключен?
  • Python - лучший язык программирования в мире.