2016-12-29 140 views
0

为什么malloc分配6个字节char类型,但我需要2个字节。 如果我分配1个字节,他分配5个字节。 我不明白为什么。C,Visual Studio中的Malloc

#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'都不是以null结尾的,一个字符串的最后一个字符应该是''\ 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

零终止添加到一个char数组做:

someCharArray[someIndex] = '\0'; 

因此,对于你的代码做两件事情:

1)分配1个多字节,从而y OU的余地零终止

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

为什么的malloc分配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库函数都希望传递给它们的字符串以null结尾,因此默认情况下应始终以null结束字符串(除非通过其他方式传递大小)。