【发布时间】:2015-12-17 09:48:03
【问题描述】:
这是一个基本的例子:
#include <all the basic stuff>
int main(void) {
char *name = (char *) malloc(2 * sizeof(char));
if(name == NULL) {
fprintf(stderr, "Error: Unable to allocate enough memory!\n");
return EXIT_FAILURE;
}
strcpy(name, "Bob Smith");
printf("Name: %s\n", name);
free(name);
return EXIT_SUCCESS;
}
因为我只分配了 2 个字节的信息(2 个字符),所以当我执行 strcpy 时应该会出现某种错误,对吧?这不会发生,它只是将字符串复制过来,打印出来,释放内存并成功退出。为什么会发生这种情况,如何正确使用 malloc?
【问题讨论】:
-
否;你得到未定义的行为,未定义行为的一个有效选项是“它似乎按预期工作”(这意味着“直到它没有”,这总是发生在最不方便的时间,例如当老板和大客户正在观看演示,或在产品交付生产后立即观看)。由于
malloc()可能已经分配了一个16 字节的空间(您只能合法访问其中的2 个字节),所以您可能很干净。或者free可能已经破坏了你的内存分配系统,但是由于你不再做任何事情,所以没有人注意到。 -
这是未定义的行为。 C在内存访问等方面不牵你的手。你想覆盖一堆内存,没问题!您可以使用 strncpy() 来限制复制的#bytes。
-
"当我执行 strcpy 时应该有某种错误,对吧?"不。因为,正如 strcpy 手册页的第一段所述:“目标字符串 dest 必须足够大以接收副本。小心缓冲区溢出!(请参阅错误。)”换句话说:这是你的责任。你最好使用 strncpy。
-
两个人建议使用
strncpy();我反对这个建议,因为strncpy()对大多数人来说有两种不良行为。首先,也是迄今为止最重要的一点,尤其是在这种情况下,当它不复制整个字符串时,它不会以空值终止字符串。第二个是如果你有一个很大的目标空间(比如 2 KiB)并且你将一个小字符串复制到其中(strncpy(space, 2048, "hi")),那么strncpy()将写入 2046 个空字节,而不仅仅是终止字符串所需的那个.如果您知道这些问题并且可以承受后果,请仅使用strncpy()。 -
再说一遍,不要投射
malloc()返回值!
标签: c memory-management malloc allocation