2016-12-29 4 views
0

Почему malloc выделяет 6 байтов char типов, но мне нужно 2 байта. Если я выделяю 1 байт, он выделяет 5 байтов. Я не понимаю, почему.Malloc in C, Visual Studio

#include "stdlib.h" 

int  main() 
{ 
    char *lin = malloc(2); 
    lin[0] = 'a'; 
    lin[1] = 'b'; 
    char *line = (char *)malloc(sizeof(char) * 2); 
    line[0] = 'z'; 
    line[1] = 'b'; 

    printf("lin = %s\nline = %s\n", lin, line); 

    get_next_line(fd, line); 
    return (0); 
} 

Это показывает, что консоль

lin = ab¤¤¤¤ 
line = zb¤¤¤¤ 
+7

Нет строковых терминаторов '' \ 0'', поэтому ваш код демонстрирует * неопределенное поведение *. Для этого вы должны выделить (по крайней мере) еще один байт памяти и сами написать терминаторы. –

+1

Ваши строки 'lin' и' line' не имеют нулевого конца, последний символ строки должен быть '' \ 0'' (индекс 1 в вашем случае). В противном случае печать строки с printf печатает все до '' \ 0'', что является UB. – pbn

+1

В любом случае диспетчер памяти не обязан выделять * любой * нечетный размер, поэтому при запросе 1 байт или 13 байт фактический размер может быть округлен до некоторого большего значения (например, 8 или 16 байт для пример). –

ответ

2

В C, строка из ASCII символа представлена ​​в виде последовательности байт отличных от нуля, за которыми следует байты с нулевым значением, см Null-terminated byte strings. Строка "ab" представлена ​​в виде массива, который содержит значения 0x61, 0x62, 0x00.

Пример:

string:  'a' | 'b' | 
memory:  0x61 | 0x62 | 0x00 

Быстрое исправление:

char *lin = malloc(3); // allocate one more char 
lin[0] = 'a'; 
lin[1] = 'b'; 
lin[2] = '\0';   // terminate the string 

В вашем случае, malloc не выделяя 6 байт, printf просто печать псевдо случайный "мусор", потому что ваша строка не нулевой прекращается.

1

Действительная строка C представляет собой массив символов с нулевым символом.

Если у вас есть массив символов без нуля-окончание этого не строки, и это незаконно, чтобы использовать его с printf и спецификатором формата %s

Чтобы добавить нулевое завершение к полукоксу массив сделать:

someCharArray[someIndex] = '\0'; 

так что для вашего кода сделать две вещи:

1) резервируют больше 1 байт так что у НУ есть место для нулевого прекращения

2) добавить Нулевые терминации

, как:

#include "stdlib.h" 

int main() 
{ 
    char *lin = malloc(3 * sizeof(char)); 
    lin[0] = 'a'; 
    lin[1] = 'b'; 
    lin[2] = '\0'; 

char *line = malloc(3 * sizeof(char)); 
line[0] = 'z'; 
line[1] = 'b'; 
line[2] = '\0'; 

    printf("lin = %s\nline = %s\n", lin, line); 

    get_next_line(fd, line); 
    return (0); 
} 
1

Почему таНос выделить 6 байт полукокса типов, но мне нужен 2 байт. Если я выделяю 1 байт, он выделяет 5 байтов.

mallocявляется не выделения слишком много памяти, вы просто доступ к памяти, вы не выделяли.

Чтобы предотвратить доступ к этой памяти, printf должен знать, где заканчиваются ваши строки. В C, обычно это делается путем добавления null-character'\0' в конце строки, например:

char *line = malloc(3); // allocate one more byte to store the null-character 
line[0] = 'a'; 
line[1] = 'b'; 
line[2] = '\0'; // insert the null-character to mark the end of the string 

printf("line = %s\n", line); 

Теперь printf знает, где строка line заканчивается, и он прекращает чтение из памяти в тот момент, и так не считывает значения мусора ¤¤¤¤, которые оказались в памяти после строки.

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