排列、分配、困惑 #包括 #包括 int main() { int*numeros=malloc(sizeof(int)*3*3); 数值[900]=10; printf(“%d”,数字[900]); 免费(numeros); 返回0; }

排列、分配、困惑 #包括 #包括 int main() { int*numeros=malloc(sizeof(int)*3*3); 数值[900]=10; printf(“%d”,数字[900]); 免费(numeros); 返回0; },c,arrays,C,Arrays,当我没有分配足够的内存时,为什么会打印出10? 我很确定我在指针上遗漏了一些重要的东西 感谢您的帮助您观察到的是未定义的行为-您在分配的缓冲区之外写入,并且可能会覆盖一些碰巧映射到进程中的内存 根据各种因素,这可能会使程序崩溃,或者什么也不做,或者损坏程序中的数据。不要这样做,只访问您合法分配的内存 另请参见。您的数组大小为9。因此,当您尝试访问超出范围的内存位置900时 您的行为未定义。也就是说,有时候它会打印垃圾值,有时候它会崩溃。因此,在使用之前一定要初始化您的变量。您缺少的是,编译器不需

当我没有分配足够的内存时,为什么会打印出10? 我很确定我在指针上遗漏了一些重要的东西


感谢您的帮助

您观察到的是未定义的行为-您在分配的缓冲区之外写入,并且可能会覆盖一些碰巧映射到进程中的内存

根据各种因素,这可能会使程序崩溃,或者什么也不做,或者损坏程序中的数据。不要这样做,只访问您合法分配的内存


另请参见。

您的数组大小为9。因此,当您尝试访问超出范围的内存位置900时


您的行为未定义。也就是说,有时候它会打印垃圾值,有时候它会崩溃。因此,在使用之前一定要初始化您的变量。

您缺少的是,编译器不需要捕获这种情况,而且通常不会。这是一种未定义的行为,这意味着对于实现的功能没有任何要求,而避免它是您的工作。通常,编译器只会编译在未定义行为的情况下看到的任何内容,而有时出现的合理行为可能会令人困惑

在这种情况下,您在
numeros
中存储了一个内存地址,在引用
*(numeros+900)
的下一条语句中,给定通常的
int
大小,该内存地址后将有3600字节。编译器为引用生成了代码。考虑到这是一种未定义的行为,编译器这样做是完全正确的,或者为此写了一封侮辱性的电子邮件给你或你的母亲;该标准没有规定任何内容。当然,它可以检测到这一点,并给您一个运行时错误,说“第7行的地址超出界限”,但不幸的是,我使用的编译器都没有给您提供这个选项


这是C编程中比较棘手的部分之一:确保您的程序定义良好。

您使用malloc为9个元素分配了内存:

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

int main()
{
    int *numeros = malloc(sizeof(int) * 3 * 3);
    numeros[900] = 10;
    printf("%d", numeros[900]);
    free(numeros);
    return 0;
}

现在,您的数组边界应该在int的限制范围内,您为int分配了内存,这是您乘以sizeof(int)的数字。它为尽可能多的int分配了内存。

您可以这样做,因为您已经从堆中分配了数组,这可能至少是32K。因此,您所做的是写入堆中的其他位置,这是“合法的”。如果将数组索引增加到128000左右,则可能会出现访问冲突。实际上,您(可能)正在覆盖已分配的其他一些数据,或者可能是实际的堆管理元数据(块头)。

,或者通过网络发送你所有的密码-类似于这个UB实例+1:你的帖子让我想起了我在某处读到的东西:C编译器信任程序员。对编译器撒谎,它会报仇的
 int *numeros = malloc(sizeof(int) * 3 * 3); 
        // allocates memory of (4) *(9) bytes==36 bytes