【问题标题】:why the compiler don't give me error?为什么编译器不给我错误?
【发布时间】:2016-02-14 20:39:34
【问题描述】:
#include <stdio.h>
#include <stdlib.h>

int main() {
    system("clear");
    int *pt = malloc(2 * sizeof *pt);
    int *tmp = NULL;
    int i;

    pt[0] = 44;
    pt[1] = 9;
    printf("pt[0] : %d\n", pt[0]);
    printf("pt[1] : %d\n", pt[1]);
    tmp = realloc(pt, 3 * sizeof *pt);
    if (!tmp) {
        printf("merde alors\n");
    } else {
        pt = tmp;
        for (i = 0; i < 5; i++) {
            pt[i] = i + 1;
            printf("pt[%d] : %d\n", i, pt[i]);
        }
    }
    //the compiler should give me an error here, because I try use an unallocated memory:
    printf("pt[%d] : %d\n", i + 8, pt[i + 8]);
    free(pt);
    return 0;
}

大家好 :) 如您所见,我不明白,我尝试使用未分配的内存,因此我希望从编译器收到一个激进的错误。 原谅我的英语不好。 感谢您的时间 :) Valgrind report :

【问题讨论】:

  • 有些东西你只需要调试。它不能显示仅在运行时出现的错误。
  • 即使数组是硬编码的,C 编译器也不会阻止您索引超出其范围。对于指针,编译器甚至可能不知道您将在运行时分配多少内存。检查数组索引由您决定。
  • 根据您的开发环境,您可能会发现一些调试工具(如 valgrind)很有用。 Valgrind 能够在运行时查明此类错误。 valgrind.org
  • 你应该从正确格式化你的代码开始。
  • 我可以确认@HenrikCarlqvist 的建议有效; valgrind 报告一次无效写入(第 20 行)和两次无效读取(第 15 和 21 行)。它还指出,在退出时仍有大量内存分配。 (它不喜欢你的行 system("clear") 根本 - 我必须先删除它。)

标签: c arrays malloc realloc


【解决方案1】:
  //the compiler should give me an error here, because i try use an unallocated memory:   
  printf("pt[%d] : %d\n", i+8, pt[i+8]);

通常你不会从编译器中得到这样的错误,由你来跟踪它。这就是 C 的美丽或黑暗的一面。如果出现 undefined behaviour (UB) 这样的问题,结果会更糟。

所以这取决于你。当存在明显的数组越界访问时,某些编译器标志或静态分析器有时可能会为您提供帮助。

许多其他相关问题也是如此,编译器不会警告你,你会得到 UB - 这就是为什么在 C 或 C++ 等语言中,你真的需要知道你在做什么。

同样在这种特殊情况下,如果您在运行时指定数组大小,编译器甚至可能不知道数组大小是多少 - 所以它不会给您错误。即使它知道,编译器也不会总是告诉你数组越界访问。

【讨论】:

  • @younesky 欢迎您,如果您对 C 或 C++ 等语言感兴趣,可以进一步阅读有关 UB 的更多信息
  • 我喜欢 C,这很难,但它给了我最大的控制权
  • @younesky:您可以使用valgrind 进行这种错误跟踪。
  • @chqrlie Ubuntu 团队说:doc.ubuntu-fr.org/valgrind Valgrind 无法检测到与代码相关的一些异常。例如,它不检查静态声明的表之外的表上的索引
  • @younesky:你试过了吗? valgrind 应该能够检测 malloc 以检测分配内存中的缓冲区溢出。您可能需要将特殊标志传递给它。阅读man 页面。
【解决方案2】:

编译器不会在编译时检查您正在访问的内存是否存在。这一切都是在运行时由您的操作系统完成的。导致分段错误发生的不是 C 本身,而是实际上是您的操作系统告诉 C 停止。

【讨论】:

  • 我没有看到 Giorgi 已经写了这个回复,我的错! :)
  • 没关系,可以有多个答案,如果你认为你的答案是在添加一些东西
猜你喜欢
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
  • 2012-05-23
  • 2011-05-29
  • 1970-01-01
  • 1970-01-01
  • 2017-11-09
  • 1970-01-01
相关资源
最近更新 更多