为什么调用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?

西奥多罗斯·查兹吉亚纳基斯

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

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

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

在以下情况下,该行为是未定义的:

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

因此,要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;
}

与此无关的是,您会注意到我没有mallocvoid*转换结果,因为a可以隐式转换为char*


最后一点:

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

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

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

来自分类Dev

在我的Node示例中添加或删除EventEmitter.call(this)没有什么区别,为什么?

来自分类Dev

单词“选择时会自动选择整个单词”选项似乎没有什么区别

来自分类Dev

在 train_test_split 中使用 'stratify' 没有什么区别。它是干什么用的?

来自分类Dev

为什么有没有什么特别的内部构造函数?

来自分类Dev

没有什么是渲染根ID

来自分类Dev

有什么区别?

来自分类Dev

有什么区别

来自分类Dev

有什么区别?

来自分类Dev

有什么区别?

来自分类Dev

有什么区别?

来自分类Dev

有什么区别?

来自分类Dev

为什么是<?用于和<?php有什么区别

来自分类Dev

系统调用和库调用有什么区别?

来自分类Dev

有/没有花括号有什么区别?

来自分类Dev

.profile和.bash_profile有什么区别?为什么我的系统上没有.profile文件?

来自分类Dev

没有足够的论点-有什么区别

来自分类Dev

有什么区别remove_reference或没有它

来自分类Dev

使用A0和A4相机校准板有什么区别?有没有 ?如果是,为什么?为什么?

来自分类Dev

core.stdc.stdlib.malloc和core.memory.GC.malloc有什么区别?

来自分类Dev

在方法的开始或结束处调用super()有什么区别?

来自分类Dev

Clojure中的导入调用有什么区别?

来自分类Dev

chroot命令和chroot()系统调用有什么区别

来自分类Dev

在Javascript中调用函数loadText与loadText()有什么区别?

来自分类Dev

调用函数和返回函数有什么区别?

来自分类Dev

调用堆栈和堆栈有什么区别?

来自分类Dev

javascript中的函数调用有什么区别?

来自分类Dev

通过sh或perl调用perl脚本有什么区别

来自分类Dev

调用函数和传递函数有什么区别?

Related 相关文章

  1. 1

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

  2. 2

    在我的Node示例中添加或删除EventEmitter.call(this)没有什么区别,为什么?

  3. 3

    单词“选择时会自动选择整个单词”选项似乎没有什么区别

  4. 4

    在 train_test_split 中使用 'stratify' 没有什么区别。它是干什么用的?

  5. 5

    为什么有没有什么特别的内部构造函数?

  6. 6

    没有什么是渲染根ID

  7. 7

    有什么区别?

  8. 8

    有什么区别

  9. 9

    有什么区别?

  10. 10

    有什么区别?

  11. 11

    有什么区别?

  12. 12

    有什么区别?

  13. 13

    为什么是<?用于和<?php有什么区别

  14. 14

    系统调用和库调用有什么区别?

  15. 15

    有/没有花括号有什么区别?

  16. 16

    .profile和.bash_profile有什么区别?为什么我的系统上没有.profile文件?

  17. 17

    没有足够的论点-有什么区别

  18. 18

    有什么区别remove_reference或没有它

  19. 19

    使用A0和A4相机校准板有什么区别?有没有 ?如果是,为什么?为什么?

  20. 20

    core.stdc.stdlib.malloc和core.memory.GC.malloc有什么区别?

  21. 21

    在方法的开始或结束处调用super()有什么区别?

  22. 22

    Clojure中的导入调用有什么区别?

  23. 23

    chroot命令和chroot()系统调用有什么区别

  24. 24

    在Javascript中调用函数loadText与loadText()有什么区别?

  25. 25

    调用函数和返回函数有什么区别?

  26. 26

    调用堆栈和堆栈有什么区别?

  27. 27

    javascript中的函数调用有什么区别?

  28. 28

    通过sh或perl调用perl脚本有什么区别

  29. 29

    调用函数和传递函数有什么区别?

热门标签

归档