gpt4 book ai didi

c - 为什么调用 malloc() 没有区别?

转载 作者:行者123 更新时间:2023-12-04 12:05:12 24 4
gpt4 key购买 nike

这是一个基本的例子:

#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?

最佳答案

您的程序调用 undefined behavior .

未定义的行为是超出语言规范的行为。根据定义,这意味着您不能保证获得任何类型的明确定义的行为(例如错误)。该程序明确无效。

当您使用strcpy 时,该函数只是假设您传递给它的缓冲区足够大,可以容纳您要复制的字符串。如果假设错误,它会尝试写入缓冲区外的区域。如果发生这种情况,程序就属于 C 规范的这种情况,在 J.2 Undefined behavior 中:

The behavior is undefined in the following circumstances:

  • Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object

因此,要正确使用strcpy,您必须手动确保上述关于字符串长度和缓冲区长度的假设成立。为此,一种简单的方法是将缓冲区的长度保存在某处,计算您要复制的字符串的长度,然后比较它们。

例如:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
size_t bufferSize = 2 * sizeof(char);
char *name = malloc(bufferSize);
if(name == NULL) {
fprintf(stderr, "Error: Unable to allocate enough memory!\n");
return EXIT_FAILURE;
}
size_t length = strlen("Bob Smith");
if(length + 1 > bufferSize) {
fprintf(stderr, "Error: The target buffer is too small!\n");
return EXIT_FAILURE;
}
strcpy(name, "Bob Smith");
printf("Name: %s\n", name);
free(name);
return EXIT_SUCCESS;
}

作为不相关的旁注,您会注意到我 didn't cast the result of malloc ,因为 void* 可以隐式转换为 char*


最后一点:

当您试图确保代码的正确性时(无论是因为您正在学习该语言还是因为您打算发布该软件),C 的这一方面可能听起来不切实际。

这就是为什么有些工具会在您的程序执行无效操作时向您报错。 Valgrind就是这样一种工具(正如 Jonathan Leffler 在评论中提到的那样)。

关于c - 为什么调用 malloc() 没有区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32682603/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com