Вызов memset по указателю на массив?

Я не думаю, что я что-то понимаю здесь...

bool (*lookup)[100];
memset(lookup, 0, 100 * sizeof(*lookup));

Я пытаюсь инициализировать указатель на массив, выделенный стеком (указатель будет передаваться только вызовам внутри кадра стека). Memset предназначен для инициализации массива нулями.

Предыдущий код вызывает segfault, не любит ли memset указатели?


person jab    schedule 21.10.2013    source источник
comment
Где находится массив, выделенный стеком?   -  person alk    schedule 21.10.2013
comment
memset очень любит указатели; и если бы вы вызывали его в памяти, занятой указателем, memset(&loopkup, 0, sizeof(lookup)); код был бы действительным (хотя и несколько бессмысленным). Как написано, вы вызываете его с неопределенным адресом, полученным из неинициализированной переменной указателя, и поэтому это поведение undefined.   -  person WhozCraig    schedule 21.10.2013
comment
Размер, передаваемый в memset, должен соответствовать объекту, на который указывает указатель. Опубликованный код имеет неопределенное поведение, поскольку указатель не инициализирован, в противном случае опубликуйте код, который инициализирует указатель.   -  person chqrlie    schedule 08.05.2019


Ответы (1)


При выполнении

memset(lookup, 0, 100 * sizeof *lookup);

вы не инициализируете указатель, а память, на которую указывает указатель lookup.

И, скорее всего, вы не указали указатель на какую-то допустимую память до вызова memset(), поэтому запись в случайную память вызывает неопределенное поведение, которое приводит к сбою программы.

Есть несколько способов получить действующую память.

Получить его из стека следующим образом:

bool lookup_instance[100] = {0};
bool (*lookup)[100] = &lookup_instance;
/* No need to memset it to 0s as this had been done by ... = {0} already. */

или получить его самостоятельно так:

bool (*lookup)[100] = malloc(sizeof *lookup);
if (NULL == lookup) 
{
  perror("malloc() failed"):
}
else
{
  memset(lookup, 0, sizeof *lookup);
}

Самым коротким решением будет:

bool (*lookup)[100] = calloc(1, sizeof *lookup);
if (NULL == lookup) 
{
  perror("calloc() failed");
}
else
{
  /* No need to memset it to 0s as this has been done by calloc() already. */
}
person alk    schedule 21.10.2013
comment
Но 100* не имеет смысла, потому что sizeof уже получает размер массива, а не элемента. - person rodrigo; 21.10.2013
comment
@rodrigo: Хуу .. я это написал? Должно быть, это был временный провал в мозгу... в любом случае спасибо! Исправлено! - person alk; 21.10.2013
comment
@rodrigo: А, понял, я скопировал это из ОП. Проклятое копирование и вставка программ... :} - person alk; 21.10.2013
comment
У меня сложилось впечатление, что bool (*lookup)[100]; выделяет массив и возвращает указатель на его первый элемент. - person jab; 21.10.2013
comment
@jab: нет, это переменная-указатель, где тип, на который указывает, - bool[100]. - person Ben Voigt; 21.10.2013