Как сделать memset для указателя на массив?
int (*p)[2];
p=(int(*))malloc(sizeof(*p)*100);
memset(p,0,sizeof(*p)*100);
Является ли это распределение правильным?
Как сделать memset для указателя на массив?
int (*p)[2];
p=(int(*))malloc(sizeof(*p)*100);
memset(p,0,sizeof(*p)*100);
Является ли это распределение правильным?
вы можете использовать calloc
.
calloc
заменит и malloc
, и memset
.
p = calloc(100, sizeof (*p));
Я суммирую многие ответы (хотя я проигнорировал некоторые стилистические варианты в пользу собственных предпочтений).
In C:
Как использовать маллок:
int (*p)[2] = malloc(100 * sizeof(*p));
Как использовать мемсет:
memset(p, 0, 100 * sizeof(*p));
Как сделать оба в одном заявлении:
int (*p)[2] = calloc(100, sizeof(*p));
В C++ возможно то же самое, за исключением того, что вам нужно преобразовать результаты malloc
и calloc
: static_cast<int(*)[2]>(std::malloc(100 * sizeof(*p))
.
Однако C++ предоставляет альтернативные способы выделения этого:
int (*p)[2] = new int[100][2](); // like calloc.
delete[] p; // *not* delete p
C++ также предоставляет vector
, что обычно хорошо, но, к сожалению, вы не можете создать вектор массивов в стиле C. В С++ 03 вы можете обойти это следующим образом:
struct my_array {
int data[2];
};
std::vector<my_array> p(100);
// no need to free/delete anything
Я не думаю, что это обнуляет элементы, хотя могу ошибаться. Если я прав, то для обнуления нужно:
my_array initvalue = {0};
std::vector<my_array> p(100, initvalue);
другой способ представить 2 целых числа:
std::vector<std::pair<int,int> > p(100);
Если вы можете использовать Boost:
std::vector<boost::array<int, 2> > p(100);
In C++11:
std::vector<std::array<int, 2>> p(100);
Я перечислил их в порядке возрастания того, насколько они обычно хороши, поэтому используйте последний вариант, который не блокируется никакими ограничениями, с которыми вы работаете. Например, если вы ожидаете взять указатель на первый элемент одного из внутренних массивов 2-int и увеличить его, чтобы получить указатель на второй, тогда std::pair
отсутствует, потому что это не гарантирует, что это работает. .
my_array()
по умолчанию или инициализирован нулем. Это ни глобально, ни автоматически!
- person Steve Jessop; 03.10.2012
my_array(int arr[2] = NULL)
, и сделать нулевую инициализацию условной.
- person Lundin; 03.10.2012
Элегантный способ:
typedef int int_arr_2[2];
int_arr_2* p;
p = malloc(sizeof(int_arr_2)*100);
memset(p,0,sizeof(int_arr_2)*100);
Лучший способ:
typedef int int_arr_2[2];
int_arr_2* p;
p = calloc(100, sizeof(int_arr_2));
calloc, в отличие от malloc, гарантирует, что все байты равны нулю.
sizeof(int_arr_2)
элегантнее, чем sizeof(*p)
. Но это больше +1, чем -1, так что меня легко убедить ;-)
- person Steve Jessop; 03.10.2012
bool custom_allocate (int** array);
, когда выделенные данные передаются в main через параметр. Чтобы сделать это правильно, вам нужно написать malloc(sizeof(**array))
. Кроме того, синтаксис typedef также проще и понятнее для среднего программиста на C, который не привык к указателям на массивы.
- person Lundin; 03.10.2012
*array = malloc(number * sizeof(**array))
. Или some_function()->member = malloc(number * sizeof(*(some_function()->member)))
. Это не сложное правило. Но я имел в виду, что меня можно убедить, что это хороший ответ, а не то, что меня можно убедить предпочесть ваш способ написания размера. Я не могу в этом убедиться, потому что вы ошибаетесь :-) Я не возражаю против typedef для указателя на массив, но это еще один плюс.
- person Steve Jessop; 03.10.2012
*
.
- person Steve Jessop; 03.10.2012
void(* (**fptr_arr)[] )(void);
. Тогда я все равно напишу *fptr_arr = malloc(n * sizeof(fptr));
и пойму, что этот код делает намного лучше, чем sizeof(***fptr_array)
.
- person Lundin; 03.10.2012
fptr
размера n
. По-моему, вы понимаете, что он выделяет массив того, на что правильно указывает *fptr_arr
, размером n
. Если есть шанс, что *fptr_arr
является неправильным присваиванием, но мы абсолютно уверены, какой тип мы должны выделить, тогда будет яснее сделать это по-своему (хотя, к сожалению, в C код будет скомпилирован, несмотря на то, что он неправильный). Это просто не мой опыт.
- person Steve Jessop; 03.10.2012
void*
, у вас нет подсказок. Строго говоря, подобное может применяться в C++, когда вы выделяете пространство для производного класса и присваиваете указатель на базу, но я не думаю, что берусь утверждать, что вы никогда этого не сделаете.
- person Steve Jessop; 03.10.2012
Строка memset()
правильная.
Для C вам приведение malloc не требуется.
В С++, если вы все еще хотите это сделать, приведение типа должно быть таким:
p = (int(*)[2]) malloc(sizeof(*p)*100); // or `static_cast<...>
// ^^^^^^^^^
Но я бы предложил изменить ваш подход к использованию std::vector
вместо этого. Чище, лучше и «полуавтомат»:
std::vector<int*> vi(100); // or std::vector vi(100, nullptr);
Другой способ работы с необработанными указателями — использовать new[]
:
int **p = new[100](); // allocates and sets to 0
Но вы должны управлять этой памятью позже, освобождая ее с помощью delete[]
new
, поэтому приведение не требуется. И просто добавление ()
в конце выражения new
эффективно установит все выделенные значения в 0.
- person James Kanze; 03.10.2012
new/new[]
только в том случае, если есть особые требования к программированию (например, копирование является дорогостоящим или многопоточным). Всегда рекомендуется использовать std::vector
, который делает это внутри и заботится об удалении памяти.
- person iammilind; 03.10.2012
std::vector<int>
здесь было бы еще лучше.
- person James Kanze; 03.10.2012
В C (не C++) вы бы просто сделали
int (*p)[2] = malloc(sizeof(*p)*100);
memset(*p,0,sizeof(*p)*100);
то есть переменные могут быть инициализированы выражениями, а malloc
не нуждается (и не должен иметь) приведения. Тогда *p
является "lvalue" вашего типа массива, который распадается на указатель при передаче в memset
.
sizeof(*your_variable)
, чтобы никогда не ошибиться - person Eregrith   schedule 03.10.2012malloc
, аnew
. (Конечно, это только для C++.) - person James Kanze   schedule 03.10.2012new
- не единственное реальное решение, особенно не в C, как вы сказали. Если он хочет несколько массивов по 2 байта, это сделано правильно, и memset будет работать.sizeof(*p)
не разыменовывает p, он содержит только тип*p
, поэтомуint [2]
- person Eregrith   schedule 03.10.2012calloc
илиnew int[100][2]()
. - person Steve Jessop   schedule 03.10.2012