Использование 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 );