Два аргумента для вызова

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

26
задан sanjoyd 3 November 2010 в 03:02
поделиться

3 ответа

Единственное заметное отличие состоит в том, что calloc требуется для инициализации выделенного пространства нулями, в то время как в malloc такой гарантии нет. В противном случае, я думаю, есть две разные функции только по историческим причинам.

0
ответ дан casablanca 3 November 2010 в 03:02
поделиться

Я услышал два [взаимоисключающих] объяснения, почему у него есть два аргумента:

  1. calloc берет на себя ответственность за проверку переполнения при умножении. Если общий размер запрашиваемого блока слишком велик (например, переполнения size_t), calloc возвращает нулевой указатель для указания сбоя. С malloc вы должны следить за переполнением себя, что многие люди просто забывают сделать. (Хотя история стандартной библиотеки знает примеры реализаций calloc, которые игнорировали переполнение и, следовательно, работали некорректно).

  2. calloc фактически позволяет выделить больше блоков памяти, чем диапазон типа size_t, т. Е. calloc может быть в состоянии выполнить надлежащее не переполнение большого умножения своих аргументов и выделить блок результирующего размера. По этой причине, поскольку calloc использует два аргумента типа size_t, он может выделить больше блоков, чем когда-либо сможет malloc (поскольку malloc принимает только один аргумент типа size_t).

Я всегда считал, что первое объяснение правильное. Тем не менее, после прочтения некоторых постов здесь на SO у меня есть сомнения.

7
ответ дан AnT 3 November 2010 в 03:02
поделиться

calloc(x,y) эквивалентно malloc(x*y)

Но calloc делает дополнительные (устанавливая значения на 0 с помощью) memset(block, 0, x*y)

Эта функция предназначена только для приятного прохождения размер элемента и количество элементов , когда в malloc необходимо умножить эти значения, чтобы получить необходимое количество байтов, эта функция также проверяет целочисленное переполнение при умножении.

Например, если вы хотите выделить память для 12 целых чисел и хотите сделать что-то с этими целыми числами, и вы, должно быть, установили ее значения на 0, используйте calloc(12, sizeof(int))

Но если вы хотите выделить некоторый блок памяти ( 256 байт), чтобы в будущем скопировать в него некоторую строку, тогда memset для вас непригодна, тогда лучше использовать malloc(sizeof(char) * 256) или, например, malloc(sizeof(wchar_t) * 256)


void *
calloc (size_t nmemb, size_t lsize)
{
  void *ptr;
  struct __meminfo *info;
  size_t size = lsize * nmemb;

  /* if size overflow occurs, then set errno to ENOMEM and return NULL */
  if (nmemb && lsize != (size / nmemb))
    {
      set_errno (ENOMEM);
      return NULL;
    }

  /* allocate memory */
  ptr = malloc (size);

  /* get pointer to info part of chunk */
  info = __mem2info (ptr);

  /* fill memory with zeros and set __MEM_CALLOC flag */
  memset (ptr, 0, info->size);
  info->flags |= __MEM_CALLOC;

  return ptr;                   /* happy end */
}
0
ответ дан Svisstack 3 November 2010 в 03:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: