Fix sanitizer out-of-memory error (#16457)

* Fix sanitizer out-of-memory error

* Add implementation for Windows

* apply comments

* Fix1

* Fix2

* Fix3
This commit is contained in:
Oleg Pipikin 2023-03-31 05:49:45 +02:00 committed by GitHub
parent bf8e5cb4a2
commit 9cf4ee1eae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -19,21 +19,49 @@
#include<stdint.h>
#include<numeric>
#if defined(_WIN32)
#define NOMINMAX
#include <windows.h>
#else
#include <unistd.h>
#endif
namespace cnpy {
struct NpyArray {
unsigned long long GetFreeMemorySize() {
#if defined(_WIN32)
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
return status.ullAvailPhys;
#elif defined(__APPLE__)
return std::numeric_limits<unsigned long long>::max();
#else
long pages = sysconf(_SC_AVPHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size;
#endif
}
NpyArray(const std::vector<size_t>& _shape, size_t _word_size, bool _fortran_order) :
shape(_shape), word_size(_word_size), fortran_order(_fortran_order)
{
num_vals = 1;
for(size_t i = 0;i < shape.size();i++) num_vals *= shape[i];
if (word_size &&
num_vals > std::vector<char>().max_size() / word_size)
num_vals > (GetFreeMemorySize() / word_size))
throw std::length_error("NpyArray of " + std::to_string(num_vals) +
"*" + std::to_string(word_size) +
" elements is too big.");
data_holder = std::shared_ptr<std::vector<char>>(
new std::vector<char>(num_vals * word_size));
try {
data_holder = std::shared_ptr<std::vector<char>>(
new std::vector<char>(num_vals * word_size));
} catch (std::bad_alloc const &) {
throw std::length_error("NpyArray of " + std::to_string(num_vals) +
"*" + std::to_string(word_size) +
" elements is too big.");
}
}
NpyArray() : shape(0), word_size(0), fortran_order(0), num_vals(0) { }