Использование sizeof() в памяти malloc'd

Возможный дубликат:
новички вопросов о malloc и sizeof

Я пытаюсь прочитать строки в программе. Когда я заметил, что строки иногда были повреждены, я попробовал следующий код:

 void *mallocated = malloc(100);
 printf("sizeof(mallocated) = %d\n", sizeof(mallocated));

В соответствии с моей программой размер mallocated был 8, хотя я выделил для него 100 байтов. Из-за этого, всякий раз, когда я пытаюсь сохранить строку длиной более 8 байтов, все после 8-го байта иногда исчезает. Почему это происходит, и как я могу его предотвратить?

Ответ 1

Потому что размер указателя на "строку" составляет 8 байт. Вот несколько примеров использования sizeof() с их соответствующим "размером". Термин size_of() иногда обманывает людей, которые не привыкли его использовать. В вашем случае размер указателя составляет 8 байт.. ниже приведено представление типичной 32-битной системы.

sizeof (char)   = 1
sizeof (double) = 8
sizeof (float)  = 4
sizeof (int)    = 4
sizeof (long)   = 4
sizeof (long long)  = 8
sizeof (short)  = 2
sizeof (void *) = 4

sizeof (clock_t)    = 4
sizeof (pid_t)  = 4
sizeof (size_t) = 4
sizeof (ssize_t)    = 4
sizeof (time_t) = 4

Источник

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

Посмотрите мой предыдущий вопрос об этом, и вы увидите даже мое отсутствие первоначального понимания.

Ответ 2

В C89 оператор sizeof находит только размер переменной в байтах во время компиляции (в данном случае указатель void из 8 байтов). Он работает так, как вы ожидали, что он будет работать на простых массивах, поскольку их размер известен во время компиляции.

char arr[100]; // sizeof arr == 100
char *p = arr; // sizeof p == 4 (or 8 on 64-bit architectures)
char *p = malloc(100); // sizeof p == 4 (or 8). Still!

Чтобы узнать размер памяти, выделенной кучей, вам нужно отслеживать ее вручную, sizeof не поможет вам.

Ответ 3

sizeof возвращает размер указателя (void *), который вы ему дали, а не размер выделенной памяти. Вам нужно будет сохранить размер памяти в отдельной переменной, если вы хотите использовать ее позже.

Ответ 4

Вы не можете. Как указано, вы можете получить размер void * mallocated, но это не говорит вам много.

Вы не можете получить размер malloed *mallocated. То есть, нет вызова функции для возврата 100 (в вашем примере) - если вы не пишете свои собственные процедуры управления памятью.

Проще всего просто запомнить его где-то... может быть....

stuct {
  void *data;
  unsigned int size
 } myStructureWhichRemebersItsSize;

myStructureWhichRemebersItsSize *someData;
someData.data = malloc(100);  // and check for NULL
someData.size = 100;

Ответ 5

void* - это тип местоположения в памяти, если вы не знаете, что он содержит. Его следует избегать.

char* - это тип значения, указывающего на некоторое место в памяти, которое содержит char. Идентификация местоположения в памяти занимает восемь байтов.

sizeof указывает, сколько байтов занимает определенный тип. Не сколько из них было выделено malloc, а только то, сколько памяти компилятор знает, какой тип должен взять. Применение значений sizeof к значениям часто считается плохим стилем, и, как упоминалось здесь, иногда вызывает интеллектуальное поведение на C99.

char[100] тип значения, который содержит 100 символов. char[100] a; - это строка из 100 char в стеке.

char(*)[100] - это тип указателя на значение, которое содержит 100 символов. char(*b)[100]; делает b равным 100 символам, возможно, в куче. Вероятно, вам нужно

char (*s)[100] = malloc( sizeof( char[100] ) );
printf( "%u byte pointer to %u bytes of size %u elements\n",
  sizeof s, sizeof *s, sizeof **s );