我不太确定malloc
到底是如何工作的。
#include <stdio.h>
#include <stdlib.h>
int main() {
char * string = (char*) malloc(sizeof(char));
string = "abc";
int * test = (int*) malloc(1 * sizeof(int));
*(test) = 5;
*(test + 1) = 6;
}
我预计这会输出一个错误,因为我指定给字符串的值大于一个字符,但它似乎编译得很好。
我有几个问题:
"字符串"现在保存在哪里?它是在我分配的一个空间之后的堆上的内存空间上吗?
为什么char让我直接指定,int只通过指针指定?
我真的不确定我在这里做什么
此代码为
string = "abc";
将字符串常数"abc"
的地址分配给作为char *
的string
变量。从malloc()
调用返回的内存地址(位于string
中)将被覆盖并丢失。
除了其他答案:
你可能想要这个:
char *string = (char*) malloc(sizeof(char) * 100); // allocate space for 100 chars
strcpy(string, "abc"); // copy the "abc" into the memoory location pointer by string
而不是这个:
char *string = (char*) malloc(sizeof(char)); // << this allocates only a single char
string = "abc";
和
*(test) = 5;
*(test + 1) = 6;
最好写成:
test[0] = 5;
test[1] = 6;
这是严格等价的,只是可读性的问题。
分配的内存太少:
如果您只为1个字符分配内存,如下所示:
char *string = (char*) malloc(sizeof(char)); // allocate space 1 char
strcpy(string, "abc"); // copy the "abc" into the memoory location pointer by string
然后你的程序仍然会编译得很好,但在运行时,字符串会被部分复制到未分配的内存中,这会导致未定义的行为(google"undefined-behavior")。
现在将‘string’保存在哪里?
char * string = (char*) malloc(sizeof(char));
string = "abc";
string
现在指向"abc"(一个文字字符串)——(堆中的)初始动态分配已经丢失,并且内存泄漏。
我将给您一个真实的例子。
假设A先生住在abc地址。现在,一些B先生开始住在某个地址"xyz"。很快,B先生的地址"xyz"更名为"abc"。现在,如果你去地址"abc",你会遇到B先生,而不是A先生。但是,这并不意味着A先生的地方被拆除了。这只是意味着A先生的居住区现在没有可到达的地址,并且已经丢失。
类似地,您将malloc
’ed的内存分配给string
,然后将string
重新分配给"abc",这意味着string
之前有一个malloc
’ed内存的地址。稍后,您的"abc"被写入某个内存,该内存的地址存储在string
中。因此,malloc
的内存永远丢失,称为内存泄漏。
编译器不会阻止您执行允许的操作,但您可能会收到1)的警告,因为string
在重新分配之前已分配且未使用(前提是要求编译器输出相关警告)。
对于2),您调用了一个恰好是malloc
的函数,该函数的参数恰好太小,不适合使用malloc
返回的指针,但由于语法正确,编译器不会抱怨。
的答案
1)string
指向"abc"
,来自malloc
的先前值丢失
2) 你也可以做test[0] = 5;
。
2)的行为是未定义的行为(访问超出范围的数组)。
最初是动态分配的,请求的大小为一个字符。
char * string = (char*) malloc(sizeof(char));
然后,指针被重新分配为字符串文字"abc"的第一个字符的地址。
string = "abc";
结果,动态分配的内存地址丢失,程序中存在内存泄漏。
如果程序是用C++编写的,那么这个语句
string = "abc";
可能会出现编译器诊断消息,因为C++中的字符串文字具有常量字符数组类型,并且指针string
必须像一样声明
const char *string;
至于字符串文字,则它们具有静态存储持续时间,并且在main获得控制之前进行分配。通常,所有字符串文字都位于所谓的字符串文字池中。
代替此语句的
string = "abc";
你可以写
strcpy( string, "abc" );
在这种情况下,程序具有未定义的行为。然而,由于函数malloc
通常分配的最小内存范围等于等于16字节的段落值,因此它可以继续成功工作。