为什么调用malloc()没有什么区别? [英] Why does calling malloc() not make a difference?

查看:59
本文介绍了为什么调用malloc()没有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个基本示例:

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

Because I'm only allocating 2 bytes of information (2 chars), there should be some sort of error when I perform strcpy, right? This doesn't happen, instead it just copies the string over, prints it out, frees the memory and exits successfully. Why does this happen, and how can I use malloc correctly?

推荐答案

您的程序会调用未定义的行为.

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

Undefined behavior is behavior that's out of the specification of the language. By definition, this means that you are not guaranteed to get any kind of well-defined behavior (such as an error). The program is explicitly invalid.

使用strcpy时,该函数仅假定传递给它的缓冲区足够大,可以容纳要复制的字符串.如果假设是错误的,它将尝试在缓冲区之外的区域中写入数据.如果发生这种情况,程序将进入 J.2未定义行为:

When you use strcpy, the function simply assumes that the buffer you pass to it is large enough to hold the string you want to copy. If the assumption is wrong, it attempts to write in an area out of the buffer. And if this happens, the program falls into this case of the C specification, in J.2 Undefined behavior:

在以下情况下,行为是不确定的:

The behavior is undefined in the following circumstances:

  • 将指针加或减到数组对象或整数类型之外或所产生的结果不会指向同一数组对象或仅指向同一数组对象

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

Thus, to use strcpy correctly, you must manually ensure that the above assumptions about the string's length and the buffer's length hold. To do that, an easy way is to keep the buffer's length saved somewhere, calculate the length of the string you want to copy, and compare them.

例如:

#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;
}

作为无关的旁注,您会注意到我没有强制转换malloc 的结果,因为void*可以隐式转换为char*.

As an unrelated side note, you'll notice that I didn't cast the result of malloc, because a void* is implicitly convertible to char*.

作为最后的提示:

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

This aspect of C may sound impractical when you're trying to ensure the correctness of your code (either because you're learning the language or because you intend to release the software).

这就是为什么有一些工具会在您的程序执行无效操作时为您提供错误信息. Valgrind 是一种这样的工具(如乔纳森·莱夫勒(Jonathan Leffler)在评论中提到的那样).

This is why there are some tools that offer to give you an error whenever your program does something invalid. Valgrind is one such tool (as was mentioned by Jonathan Leffler in the comments).

这篇关于为什么调用malloc()没有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆