Узнать размер выделенной памяти
можем ли мы проверить, выделен ли указатель, переданный функции, с памятью или нет в C?
У меня есть wriiten моя собственная функция в C, которая принимает указатель символа -buf [указатель на буфер] и размер - buf_siz [размер буфера]. Фактически перед вызовом этой функции пользователь должен создать буфер и выделить ему память buf_siz.
Так как есть вероятность, что пользователь может забыть сделать выделение памяти и просто передать указатель на мою функцию я хочу проверить это. Так что есть ли способ проверить мою функцию, чтобы увидеть, действительно ли указатель передан с объемом памяти buf_siz .. ??
EDIT1: кажется, что нет стандартной библиотеки, чтобы проверить его .. но есть грязный хак, чтобы проверить его .. ??
EDIT2: Я знаю, что моя функция будет использоваться хороших программистов . Но я хочу знать, можем ли мы проверить или нет. . если можно, я бы хотел послушать ..
Вывод: Таким образом, невозможно проверить, выделен ли конкретный указатель с памятью или нет в функции
вы не можете проверить, за исключением некоторых конкретных хаков реализации.
указатели не имеют никакой информации с ними, кроме того, где они указывают. Лучшее, что вы можете сделать, это сказать: "я знаю, как этой версии компилятор выделяет память, так что я разыменования памяти, переместите указатель 4 байта, проверьте размер, чтобы убедиться, что он соответствует. "и так далее. Вы не можете сделать это стандартным образом, так как распределение памяти определено реализацией. Не говоря уже о том, что они, возможно, не динамически выделили его вообще.
вы просто должны предположить, что ваш клиент знает, как программировать в C. единственным решением, которое я могу придумать, было бы выделить память самостоятельно и вернуть ее, но это вряд ли небольшое изменение. (Это более крупное изменение дизайна.)
для решения, специфичного для платформы, вас может заинтересовать функция Win32 IsBadReadPtr (и других, подобных ей). Эта функция сможет (почти) предсказать, получите ли вы ошибку сегментации при чтении из определенного куска памяти.
однако, это вовсе не защитите вас в общем случае, потому что операционная система ничего не знает о C runtime heap manager, и если вызывающий объект проходит в буфере, который не так велик, как вы ожидайте, что остальная часть блока кучи будет по-прежнему читаться с точки зрения ОС.
приведенный ниже код - это то, что я использовал один раз, чтобы проверить, пытается ли какой-то указатель получить доступ к незаконной памяти. Механизм состоит в том, чтобы вызвать SIGSEGV. Ранее сигнал SEGV был перенаправлен на частную функцию, которая использует longjmp для возврата к программе. Это своего рода хак, но он работает.
код можно улучшить (используйте "sigaction" вместо "signal" и т. д.), Но это просто чтобы дать идею. Также он переносится на другие версии Unix, для Windows я не уверен. Обратите внимание, что SIGSEGV сигнал не должен использоваться где-то еще в вашей программе.
Я однажды использовал грязный хак на моем 64-битном Solaris. В 64бит режиме куче начинается 0х1 0000 0000. Сравнивая указатель, я мог определить, является ли он указателем в сегменте данных или кода p < (void*)0x100000000 указатель в куче p >(void*)0x100000000 или указатель в области отображения памяти (intptr_t)p < 0 (mmap возвращает адреса из верхней части адресуемой области). Это позволило в моей программе удерживать выделенные и сопоставленные с памятью указатели на одной карте, а мой модуль карты освобождал правильный указатели.
но этот трюк очень непортящийся, и если ваш код полагается на что-то подобное, пришло время переосмыслить архитектуру вашего кода. Ты, наверное, делаешь что-то не так.
Я всегда инициализировать указатели значением null. Поэтому, когда я выделяю память, она меняется. Когда я проверяю, выделена ли память, я делаю pointer != NULL . Когда я освобождаю память, я также устанавливаю указатель на null. Я не могу придумать, как сказать, было ли выделено достаточно памяти.
это не решает вашу проблему, но вы должны верить, что если кто-то пишет программы на C, то он достаточно квалифицирован, чтобы сделать это правильно.
нет, в общем, нет способа сделать это.
кроме того, если ваш интерфейс просто "передает указатель на буфер, где я буду помещать материал", то вызывающий может выбрать не чтобы выделить память вообще, а вместо этого использовать буфер фиксированного размера, который статически выделяется или автоматическая переменная или что-то еще. Или, возможно, это указатель на часть большего объекта в куче.
Если ваш интерфейс специально говорит: "Передайте указатель на выделенный память (потому что я собираюсь освободить ее)", то вы должны ожидать, что звонящий сделает это. Неспособность сделать это не то, что вы можете обнаружить.
один хак, который вы можете попробовать, проверяет, указывает ли ваш указатель на стек выделенной памяти. Это не поможет вам в целом, поскольку выделенный буфер может быть небольшим или указатель указывает на некоторый раздел глобальной памяти (.ОНБ. ,константа. . ).
чтобы выполнить этот хак, вы сначала сохраните адрес первой переменной в main (). Позже, вы можете сравнить этот адрес с адресом локальной переменной в конкретной рутины. Все адреса между обоими адресами расположены на стек.
Я знаю, что это старый вопрос, но почти все возможно в C. Здесь уже есть несколько хакерских решений, но действительный способ определить, правильно ли выделена память, - использовать oracle вместо malloc , calloc , realloc и free . Это тот же способ тестирования фреймворков (например, cmocka) может обнаруживать проблемы с памятью (ошибки seg, не освобождая память и т. д.). Вы можете поддерживать список адресов памяти, выделенных по мере их выделения и просто проверьте этот список, когда пользователь хочет использовать функции. Я реализовал что-то очень похожее для моей собственной платформы тестирования. Пример кода:
у вас были бы аналогичные функции для calloc , realloc и free , каждая обертка с префиксом __wrap_ . Настоящий malloc доступен через использование __real_malloc (аналогично для других функций, которые вы обертываете). Всякий раз, когда вы хотите проверить, действительно ли выделена память, просто повторите связанный memory_ref перечислите и найдите адрес памяти. Если вы найдете его, и он достаточно большой, вы точно знаете, что адрес памяти не приведет к сбою вашей программы; в противном случае верните ошибку. В файле заголовка, который использует ваша программа, вы добавите следующие строки:
мои потребности были довольно простыми, поэтому я реализовал очень простую реализацию, но вы можете себе представить, как это может быть расширено, чтобы иметь лучшую систему отслеживания (например, создать struct , которая отслеживает местоположение памяти в дополнение к размер.) Затем вы просто компилируете код с помощью
недостатком является то, что пользователь должен скомпилировать свой исходный код с вышеуказанными директивами; однако, это далеко не хуже, чем я видел. Есть некоторые накладные расходы на выделение и освобождение памяти, но всегда есть некоторые накладные расходы при добавлении безопасности.
вы не можете проверить что-либо доступное в стандарте C. Даже если ваш конкретный компилятор должен был предоставить функцию для этого, это все равно было бы плохой идеей. Вот пример того, почему:
как все говорили, нет стандартного способа сделать это.
до сих пор никто не упомянул 'Написание Твердого Кода' Стив Магуайр. Хотя бичевал в некоторых квартала, в книге есть главы по теме управления памятью и обсуждается, как с осторожностью и полным контролем над всем выделением памяти в программе вы можете сделать так, как вы просите, и определить, является ли указатель, который вам дан, действительным указателем на динамически выделенный память. Однако, если вы планируете использовать сторонние библиотеки, вы обнаружите, что немногие из них позволяют изменить процедуры выделения памяти на свои собственные, что значительно усложняет такой анализ.
Я не знаю, как это сделать из вызова библиотеки, но в Linux вы можете посмотреть /proc//numa_maps . Он покажет все разделы памяти, а третий столбец скажет "куча"или " стек". Вы можете посмотреть необработанное значение указателя, чтобы увидеть, где она.
поэтому указатели, которые находятся выше 0x01167000, но ниже 0x7f39904d2000, расположены в куче.
Вы можете, позвонив malloc_size(my_ptr) на malloc/malloc.h он возвращает размер, который malloc выделил для вас для вашего указателя, и 0, если указатель не был выделен. Имейте в виду, что malloc изменяет размер выделенного блока, чтобы гарантировать, что наиболее ограничительная переменная типа может быть разыменована из этого указателя и выровнять память. Поэтому, если вы вызываете malloc (1) (а также malloc (0)), malloc фактически возвращает 16 байт (на большинстве машин), потому что самый ограничительный тип имеет размер 16 байт
Нет, ты не можешь. Вы заметите, что никакие функции в стандартной библиотеке или где-либо еще не делают этого. Это потому, что нет стандартного способа сказать. Вызывающий код просто должен принять на себя ответственность за правильное управление памятью.
в целом пользователи lib несут ответственность за проверку и проверку ввода. Вы можете увидеть ASSERT или что-то в коде lib, и они используются только для отладки perpose. это стандартный способ при написании C / C++. в то время как многие кодеры любят делать такую проверку и проверку в своем коде lib очень тщательно. действительно "плохие" привычки. Как указано в IOP/IOD, интерфейсы lib должны быть контрактами и четко указывать, что будет делать lib, а что нет, и что должен делать пользователь lib, а что нет необходимый.
указатель неинициализированное именно, что - неинициализированное. Он может указывать на что угодно или просто быть недопустимым адресом (т. е. не сопоставленным с физической или виртуальной памятью).
практическое решение состоит в том, чтобы иметь подпись действительности в указанных объектах. Создайте оболочку malloc (), которая выделяет запрошенный размер блока плюс размер структуры подписи, создает структуру подписи в начале блока, но возвращает указатель на местоположение после подписи. Затем можно создать функцию проверки, которая принимает указатель, использует отрицательное смещение для получения структуры проверки и проверяет ее. Конечно, вам понадобится соответствующая бесплатная () оболочка, чтобы аннулировать блок путем перезаписи подписи действительности и выполнить свободный от истинного запуска выделенного блока.
в качестве структуры валидности вы можете использовать размер блока и его дополнение. Таким образом, у вас есть не только способ проверки блока (XOR the two значения и сравниваются с нулем), но у вас также есть информация о размере блока.
в компьютерах почти никогда не бывает "никогда". Кросс-платформенный путь над ожидаемым. После 25 лет я работал над сотнями проектов, все они предвосхищали кросс-платформу, и она так и не материализовалась.
очевидно, что переменная в стеке будет указывать на область в стеке, которая почти линейна. Кросс-платформенные сборщики мусора работают, отмечая верхнюю или (нижнюю) часть стека, вызывая небольшую функцию, чтобы проверить, растет ли стек вверх или вниз, а затем проверка указателя стека, чтобы узнать, насколько велик стек. Это ваш выбор. Я не знаю машину, которая не реализует стек таким образом (либо вверх, либо вниз.)
вы просто проверяете, находится ли адрес нашего объекта или указателя между верхней и нижней частью стека. Вот как вы узнаете, является ли это переменной стека.
слишком просто. Эй, это правильный c++? Нет. Правильно важно? За 25 лет я повидал гораздо больше правильных оценок. Что ж, давайте скажем так: если вы занимаетесь хакерством, вы не занимаетесь настоящим программированием, вы, вероятно, просто перестраиваете то, что уже сделано.
насколько это интересно?
есть простой способ сделать это. Всякий раз, когда вы создаете указатель, напишите вокруг него обертку. Например, если программист использует библиотеку для создания структуры.
убедитесь, что он выделяет память, используя вашу функцию, такую как
если эта struct_var содержит динамически выделяемую память, например,
если определение struct_type было
затем в вашей функции init_struct_type () выполните это
таким образом, если он не выделит строку temp->значению, она останется нулевой. Вы можете проверить функции, использующие эту структуру, если строка имеет значение NULL или нет.
еще одна вещь, если программист настолько плох, что он не может использовать ваши функции, а скорее напрямую обращается к нераспределенной памяти, он не заслуживает использования вашей библиотеки. Просто убедитесь, что в вашей документации указано все.
указатель трекер, отслеживает и проверяет валидность указателя
создать память инт * ПТР = функция malloc(оператор sizeof(тип int) * 10);
Подскажите, пожалуйста, можно ли узнать, сколько памяти выделено под массив, на который ссылается указатель, к примеру int *array ?
Суть проблемы в том, что есть файл, в котором на первой строке записано кол-во строк матрицы, на второй строке файла - кол-во столбцов матрицы, далее записана сама матрица (строка матрицы в отдельной строке файла). Все это дело считывается в одномерный массив структур (в структуре хранится позиция элемента в двумерной матрице и само значение элемента)
После считывания первых двух строк из файла, создаю указатель Matrix *values на массив структур и маллочу нужное кол-во памяти.
И есть заголовок функции, которую надо реализовать
В эту функцию передается сам массив структур, строка и столбец элемента, который надо получить. В нее НЕ передается ни кол-во элементов, ни кол-во строк и столбцов в исходной двумерной матрице.
Оперируя этими данным необходимо как-то вытащить элемент из одномерного массива. Организовать цикл не получается, потому что не знаю его границ. Думал, может можно как-то узнать размер памяти, которую выделяет malloc и от этого как-то отталкиваться.
PS. заголовок функции менять нельзя. Поля структуры можно
Добавлено через 10 минут
Ошибся, поля структуры тоже менять нельзя. Они прописаны в задании.
Сделать проверку, выделил ли malloc память
Добрый день! Нужна помощь по коду: в строках (34, 45 и 48), где я использовал malloc нужно тут же.
Выделение памяти под структуры (malloc)
Доброго времени суток! Нужна помощь в выделении памяти для структуры с указателями. Можете.
Нужно, чтобы память под массив выделялась не через: new — delete, а через оператор malloc (calloc) — free
Ребят, есть программа, которая работает, но нужно, чтобы память под массив выделялась не через .
Сколько выделится памяти под битовое поле?
Доброго времени суток! Разбираю одну програмку, а именно реализацию телефонной базы данных. Может.
1. Можно использовать глобальные переменные.
2. Вопрос лучше задать не нам, а автору задания (фиг знает, что он имел в виду, когда составлял).
можно ли узнать, сколько памяти выделено под массив, на который ссылается указатель, к примеру int *array ?
Нет. Если такая информация нужна, то программист сам должен позаботиться о том, чтобы сохранить её в отдельную переменную и протащить её всюду, где эта информация нужна
geniuss7, Есть один хакерский способ, только вы его, пожалуйста, никому не рассказывайте, а то меня побьют камнями
Дело в том, что самая естественная реализация маллока состоит в том, что в куче выделяется память на int + требуемый размер. И возвращается указатель именно на память этого размера.
И если p = malloc(. ), то k = *((int)p - 1) и даст (может быть) размер выделенной памяти в байтах.
Только этого вам (и мне) никто не обещал. Разработчик функции malloc мог поступить и по другому.
Поэтому мой совет - прочитайте этот пост и забудьте. Лучше всего - сожгите (перед прочтением)
Evg, успел получить на почту текст вашего поста, до его "del".
Но, наверное понятно, о чем речь идет?
Хотя я применять этот прием никому не советую (и сам не применял никогда)
На твоей системе, на которой ты экспериментировал, возможно оно и заработает. Но на другой системе оно скорее всего не взлетит
Внутри себя менеджер памяти, в котором реализованы malloc, realloc и free, конечно же знает, где сколько памяти выделено. Но по стандарту сия информация не обязана предоставляться наружу, а потому никто её и не предоставляет. Каждая реализация библиотеки работает по своему.
Я уверен, что ты и сам это хорошо понимаешь. Просто написал для тех, кто прочтёт твой пост, по факту увидит, что оно работает, и будет думать, что так можно работать всегда, несмотря на то, что русским языком было написано, что так делать нельзя
Добавлено через 52 секунды
Это я затупил, невнимательно прочёл твою формулу. Т.е. возражения получились, мягко говоря, совсем не к тому, что ты написал
Как мне узнать количество char-ов которые выделены с помощью new??
вот только это для malloc. Да, new/new[] под капотом может использовать malloc напрямую, а может и нет. Плюс нет абсолютно никакой гарантии, что тот указатель, который возвращает malloc, будет возвращает и с помощью new.
@KoVadim стандартный оператор new[] действительно внутри себя вызывает malloc() и если та возвращает NULL , бросает исключение. Более того, если выделяется массив классов, содержащих деструктор, то длина массива помещается перед возвращаемым оператором new[] указателем - т.е., сам указатель на такой массив смещается относительно выделенной области на 4 байта (во всяком случае в g++ так). Подзырено в дизассемблере))
2 ответа 2
Насколько мне известно (но я могу ошибаться) не существует документированного способа узнать размер динамически выделенного массива по его указателю. Соответственно, возможны следующие варианты:
Вместе с указателем на массив сохранять размер последнего в переменной. Например:
char* pMyArray = new char[NUM_CHARS];
int myArrayLen = NUM_CHARS;
Следует из (1) - использовать класс-обёртку, представляющий пару "указатель на массив, размер массива". Например, в черновом варианте это может выглядеть так:
Скажем так, это ужасный вариант. Вот функция create не нужна. Этим конструктор должен заниматься. А если эту функцию позовут дважды? В деструкторе лишний if и присваивание.
Можно использовать strlen(char_arr) , это выдаёт количество именно использованных char а не выделенных. Так-же можете попробовать sizeof(char_arr) / sizeof(char) , но это работает только при создании массива таким образом: char str[10]; .
И да, для использования strlen должна быть подключена библиотека iostream либо string, но если вы не хотите их использовать, вот простенький аналог:
Переменная len будет содержать количество ** использованных** символов в этом char массиве.
strlen считает кол-во символов до первого нулевого символа. А что такое "использованных char" - это большая загадка. (хотя я догадываюсь).
@KoVadim под "использованными" я и имею ввиду символы до нулевого, просто многие не знают, что такое нулевой символ
@NekitKuzmenko, комментарий от HolyBlackCat, который я отметил, является ответом на вопрос: "как узнать размер , выделенной в динамической памяти?",. А вы рассказываете про статический массив и определения длины строки
есть ли способ В C узнать размер динамически выделенной памяти?
есть ли способ узнать размер памяти, связанной с p ?
Q. Поэтому я могу запросить malloc пакет, чтобы узнать, насколько большой выделенный блок?
A. К сожалению, нет стандартного или портативного способа. (Некоторые компиляторы предоставляют нестандартные расширения. Если вам нужно знать, вы должны будете следить за этим сами. (См. также вопрос 7.28.)
нет стандартного способа найти эту информацию. Однако некоторые реализации предоставляют такие функции, как msize для этого. Например:
- _msize на Windows
- malloc_size на MacOS
- malloc_usable_size на системах с glibc
имейте в виду, что malloc выделит минимум запрошенного размера, поэтому вы должны проверить, является ли вариант msize для вашего реализация фактически возвращает размер объекта или памяти, фактически выделенной в куче.
некоторые вещи, которые вы могли бы сделать с областью памяти, требуют только место старта регионе. Такие вещи включают работу с нулевыми строками, манипулируя первым n байт области (если известно, что область по крайней мере такая большая) и так далее.
в принципе, отслеживание длины области является дополнительной работой, и если C сделал это автоматически, иногда это будет делать это без необходимости.
многие библиотечные функции (например, fread() ) требует указатель на начало области, а также размер этой области. Если вам нужен размер региона, вы должны отслеживать его.
да, реализации malloc () обычно следите за размером региона, но они могут сделать это косвенно, или округлить его до некоторой ценности, или не держать его вообще. Даже если они поддерживают его, поиск размера таким образом может быть медленным по сравнению с отслеживанием его самостоятельно.
Если вам нужна структура данных, которая знает, насколько велика каждая область, C может сделать это за вас. Просто используйте структуру, которая отслеживает, насколько велика область, а также указатель на регион.
нет, библиотека времени выполнения C не предоставляет такой функции.
некоторые библиотеки могут предоставлять функции, специфичные для платформы или компилятора, которые могут получить эту информацию, но обычно способ отслеживать эту информацию находится в другой целочисленной переменной.
Как все уже говорили: Нет, нет.
кроме того, я бы всегда избегал всех функций, специфичных для поставщика, потому что, когда вы обнаружите, что вам действительно нужно их использовать, это обычно признак того, что вы делаете это неправильно. Вы должны либо хранить размер отдельно, либо не знать его вообще. Использование функций поставщика-Это самый быстрый способ потерять одно из основных преимуществ написания на C, переносимость.
вот лучший способ, который я видел, чтобы создать указатель с тегами для хранения размера с адресом. Все функции указателя будут работать так, как ожидалось:
вы также можете реализовать оболочку для malloc и бесплатно добавлять теги (например, выделенный размер и другая метаинформация) перед указателем вернулся Мэллок. Это фактически метод, который компилятор C++ объекты теги ссылки на виртуальные классы. Вот один работает пример:
преимущество этого метода над структурой с размером и указатель
это то, что вам нужно только заменить malloc и бесплатные звонки. Все другие операции указателя не требуют рефакторинга.
Я ожидал бы, что это будет зависеть от реализации.
Если вы получили структуру данных заголовка, вы можете вернуть ее на указатель и получить размер.
Если вы используете malloc, то вы не можете получить размер.
С другой стороны, если вы используете OS API для динамического выделения памяти, например Windows функции кучи, тогда это возможно сделать.
этот код, вероятно, будет работать на большинстве установок Windows:
это может сработать, небольшое обновление в вашем коде:
но это приведет к 1, то есть памяти, связанной с p если это char* . Если это int* тогда результат будет 4.
нет никакого способа узнать общее распределение.
Ну, теперь я знаю,что это не ответ на ваш конкретный вопрос, однако мышление вне коробки, как это было. Мне пришло в голову, что вам, вероятно, не нужно знать. Хорошо, хорошо, нет, я не имею в виду, что у вас плохая или неортодоксальная реализация. Я имею в виду, что вы, вероятно (не глядя на свой код, я только догадываюсь), вы хотите знать, могут ли ваши данные поместиться в выделенную память, если это так, то это решение может быть лучше. Он не должен предлагать слишком много накладных расходов и решит вашу проблему "подгонки", если это действительно то, что вы обрабатываете:
или если вам нужно сохранить старое содержание:
конечно, вы можете просто использовать:
и покончим с этим.
все, кто говорит вам, что это невозможно, технически правильно (лучший вид правильного).
по техническим причинам, это плохая идея полагаться на подсистему malloc, чтобы точно сказать вам размер выделенного блока. Чтобы убедиться в этом, представьте, что вы пишете--21-->большой приложение, с несколькими различными распределителями памяти-возможно, вы используете raw libc malloc в одной части, но c++ operator new в другой части, а затем некоторые конкретные окна API в еще одной части. Итак, у вас есть все виды void* летают. Написание функции, которая может работать на любой из этих void* s невозможно, если вы не можете каким-то образом определить по значению указателя, из какой из ваших куч он пришел.
таким образом, вы можете обернуть каждый указатель в своей программе некоторым соглашением, которое указывает, откуда пришел указатель (и куда его нужно вернуть). Например, в C++ мы называем это std::unique_ptr (для указателей, что нужно быть operator delete ' d) или std::unique_ptr (для указателей, которые должны быть возвращены через некоторый другой механизм D ). Вы могли бы сделать то же самое в C, если вы хотели. И как только вы заворачиваете указатели в более безопасные объекты в любом случае, это всего лишь маленький шаг к struct SizedPtr < void *ptr; size_t size; >и тогда вам больше не нужно беспокоиться о размере распределения.
однако.
здесь и веские причины, почему вы могли бы законно хотите узнать фактический базовый размер распределения. Например, возможно, вы пишете инструмент профилирования для своего приложения, который будет сообщать фактический объем памяти используется каждой подсистемы, а не только объем памяти, что программист мысль он использовал. Если каждое из ваших 10-байтовых распределений тайно использует 16 байтов под капотом, это хорошо знать! (Конечно, будут и другие накладные расходы, которые вы не измеряете таким образом. Но есть еще другие инструменты для это работа.) Или, может быть, вы просто расследуете поведение realloc на вашей платформе. Или, может быть, вы хотели бы "округлить" способность растущего распределения, чтобы избежать преждевременное перераспределение в будущем. Пример:
потом в другой функции я хочу знать размер памяти, на который указывает ab указатель. Есть ли способ, которым я могу это узнать?--1--> указывает на 10 символов памяти?
это глубокий секрет, который только free() знает наверняка. Это, вероятно, в вашей системе, но полностью зависит от реализации.
немного неловко, но если вы хотите сохранить все вместе:
Я изменил тип данных int чтобы сделать код более общего шаблона.
нет, у вас нет стандартного способа сделать это. Вы должны передать размер указанной памяти вместе с указателем, это общее решение.
вы не можете (переносно в любом случае). Вы должны следить за размером сами.
некоторые реализации malloc может дать вам API для доступа к этой информации, но в стандарте для этого нет никаких положений.
нет способа, вы должны сохранить размер выделенной памяти в другой переменной.
нет, к сожалению.
вам нужно передать размер блока вместе с указателем.
теперь, как говорится, есть не портативные хаки для этого, но на них небезопасно полагаться.
Если вы знаете со 100% уверенностью, что память была выделена через malloc (), вы можете перемотать указатель на несколько байтов и проверить "узел malloc", который используется для отслеживания, какие части памяти были выделены, а какие нет. Однако я не могу подчеркнуть этого достаточно-никогда не полагайтесь на это.
размер-это то, что вы прошли в malloc , вы можете использовать глобальную переменную или макрос, чтобы помнить его.
невозможно вывести размер выделенной памяти из самого указателя. С ab Это char * , sizeof(ab) это то же самое, что sizeof(char *) , что, очевидно, не совпадает с размером выделенного куска памяти.
так ты назвала malloc с требуемым размером, вы знаете, что размер. Передайте это число вместе с указателем на функцию, которая должна знать размер.
У меня была структура и указатель char, указывающий на ее адрес памяти. Поэтому, связывая это с вашим вопросом, я хотел найти размер местоположения памяти, на которое он указывал, т. е. размер структуры. Поэтому логически, что вы делаете, это найти размер объекта, на который создается указатель. Это сработало для меня:
таким образом, значение x сообщает мне размер местоположения памяти, на которое указывает буфер указателя.
Читайте также:
- Этот вариант обновления недоступен при запуске компьютера с использованием установочного носителя
- Настройка warframe для слабых ноутбуков
- Неожиданная ошибка произошла ошибка при переименовании временного файла текстовый файл занят
- Macbook air замена ssd samsung evo
- Провести очистку памяти beholder 2