malloc在这段代码中做了什么?

fre*_*ara 5 c c++ malloc

你能解释下面的代码吗?

str = (char *) malloc (sizeof(char) * (num+1));
Run Code Online (Sandbox Code Playgroud)
  1. 这是 malloc做什么的?
  2. 为什么num + 1用?

Joh*_*eek 29

malloc是一个在堆上分配一块内存并返回指向它的指针的函数.它与new许多语言的运算符类似.在这种情况下,它创建了一个内存块,可以在任意长度的时间内存活并具有任意大小.这本身就是相当深入的东西,这有点难以解释并且需要一个单独的问题.

num + 1为补偿空终止对字符串的结束.字符串通常需要知道它们有多长,C传统是在字符串末尾为一个额外字符分配空间,这将始终是特殊字符\0.这允许处理字符串的函数自动确定字符串的大小.例如,如果你想对字符串的每个字符做一些事情而不知道字符串有多长,你可以这样做:

const char *ptr = str;
while (*ptr != '\0') {
    process(*ptr);
    ptr++;
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*ite 13

malloc用于内存分配. num + 1是允许空终止符 - \0.


pae*_*bal 10

序言:我简直不敢相信!当我被教授C基础知识(没有双关语)时,我被这种表达困惑不解.这就是我在"解析代码"部分中详细介绍的原因.

解析代码

第一个问题是解析代码

欢迎来到暮光之城

str = (char *) malloc (sizeof(char) * (num+1));
Run Code Online (Sandbox Code Playgroud)

使用C/C++时,必须解析这种表达式,因此我们将其分解为其组件.我们在这里看到的第一件事是:

variable = (expression) function (expression) ;
Run Code Online (Sandbox Code Playgroud)

我第一次看到它时,我只是"嘿,我不相信有一种编程语言,你可以通过在函数调用的左侧和右侧放置它们的参数来调用函数!".

解析这行代码?

事实上,这一行应该是这样的:

variable = function_a (function_b (expression)) ;
Run Code Online (Sandbox Code Playgroud)

其中:

expression is sizeof(char) * (num+1)
function_b is malloc
function_a is a cast operator
Run Code Online (Sandbox Code Playgroud)

C cast运算符有点不自然

正如其他地方已经解释的那样,C风格的演员更像是

(function_a) expression
Run Code Online (Sandbox Code Playgroud)

比较自然

function_a(expression)
Run Code Online (Sandbox Code Playgroud)

这解释了整行代码的陌生感.

C++有更容易理解的东西吗?

请注意,在C++中,您可以使用这两种表示法,但您应该使用static_cast,const_cast,reinterpret_cast或dynamic_cast而不是上述表示法.使用C++强制转换,上面的代码行将是:

str = static_cast<char *> ( malloc (sizeof(char) * (num+1))  ) ;
Run Code Online (Sandbox Code Playgroud)

我的体型比你的大

sizeof是一个运营商.您可以将其视为处理类型的函数.您将类型作为参数传递,它将以字节为单位给出它的大小.

所以,如果你写:

size_t i = sizeof(char) ;
size_t j = sizeof(int) ;
Run Code Online (Sandbox Code Playgroud)

您可能(在32位Linux上)i的值为1,j的值为4.它在malloc中的使用就像是说"我想要足够的空间放置25辆4米长的车"而不是"我想要至少100米".

有关于Malloc的东西

Malloc的参数是size_t,即无符号整数.你给它的大小以字节为单位,如果成功,它会返回足够大的分配内存地址,供你用作数组.例如:

int * p = (int *) malloc (25 * sizeof(int)) ;
Run Code Online (Sandbox Code Playgroud)

然后p指向一个内存,你可以在其中并排放置25个整数,就像在索引从零到大小minux的数组中一样.例如:

p[0] = 42 ;  // Ok, because it's the 1st item of the array
p[24] = 42 ; // Ok, because it's the 25th item of the array
p[25] = 42 ; // CORRUPTION ERROR, because you are trying to
             // use the 26th item of a 25 items array !
Run Code Online (Sandbox Code Playgroud)

注意:你也有指针算术,但这超出了问题的范围.

num + 1?

C风格的字符串与其他语言字符串有些不同.字符串的每个字符都可以是任何值但不是零.因为零(也标记为\ 0)标记交流字符串的结尾.

换句话说:你永远不知道c字符串的大小,但通过搜索\ 0字符,你可以知道它的结束位置(顺便说一下,这是缓冲区溢出和堆栈损坏的一个原因).

例如,字符串"Hello"似乎有5个字符:

"Hello" seems to be an array containing 'H', 'e', 'l', 'l' and 'o'.
Run Code Online (Sandbox Code Playgroud)

但实际上,它有6个字符,最后一个是字符ZERO,使用转义字符\ 0来标注.从而:

"Hello" is an array containing 'H', 'e', 'l', 'l', 'o' and 0.
Run Code Online (Sandbox Code Playgroud)

这解释了当你想为一串"num"字符分配足够的空间时,你会分配"num + 1"个字符.


Sea*_*ean 7

malloc分配内存.

num + 1 as num是字符串中的字符数,空终止符是+1