在 C 中错误定位数组



我有以下一段代码,我希望它会失败,但似乎工作正常。 我很困惑为什么这不会导致某种分段错误。

#include <stdio.h>
#include <stdlib.h>
struct entry {
    int foo;
};
struct table {
    int size;
    struct entry* entries;
};
typedef struct table *Table;
typedef struct entry Entry;
int main() {
    Table table = malloc(sizeof(struct table));
    table->entries = malloc(sizeof(struct entry) * 1);
    (table->entries)[5].foo = 5;
    for (int i = 0; i < 10; i++) {
        printf("Entry #%d: %dn",i,(table->entries)[i].foo);
    }
}

本以为,由于我只为表>条目中的一个条目分配了足够的空间,因此访问 0 以外的任何索引都是越界的。 但是当我运行这个程序时,它会打印出 5 作为索引 5 处条目的 foo 值,其余为 0,这是正确的行为。 为什么这没有失败?

其他人会说得更好,但未定义的行为是未定义的。

它没有定义。它可能会起作用。未必。

这完全取决于这些内存位置中的内容。

你写了一个不好的位置。你读了一些其他的。你碰巧没有撞到任何东西太重要了。

你写了一个字,远远超过了你的错误区域。也许如果你做了更多的计算这会造成麻烦,因为您写入了 Malloc 的数据结构。也许不是。

正在越界访问,但这只会调用"未定义的行为"。 当您调用"未定义的行为"时,任何事情都可能发生。一种可能性是程序崩溃;另一个是程序没有崩溃并且看起来没问题。 任何一种都是可能的;它有时甚至可能崩溃,有时不崩溃。

如果您尝试了更多的内存分配,或者尝试释放内存,你更有可能看到事情出了问题。 但是,即使这样也不能保证;您可能错过了所有敏感信息(malloc() et al 用于确定分配了哪些内存和未分配哪些内存的字节数)。

你可以写:

table->entries[i].foo

你不需要(table->entries)[i].foo周围的括号,尽管它们是无害的,除了它们表明新手正在编码。

它不会失败,因为尽管您正在写入未分配的内存,但该内存完全位于合法的堆空间内。但是,您没有向内存管理器声明您正在使用该内存空间,未来的malloc()可能会尝试分配给同一区域,并且您将获得重叠的缓冲区和未定义的行为。

这是

您正在访问不属于"您的"内存位置的未定义行为。您在内存中编写了一些不是由您分配的东西,从而损坏了该内存位置。

#include <stdio.h>
#include <stdlib.h>
struct entry {
    int foo;
};
struct table {
    int size;
    struct entry* entries;
};
typedef struct table *Table;
typedef struct entry Entry;
int main() {
    Table table =(table)malloc(sizeof(struct table));
    table->entries =(entry*)malloc(sizeof(struct entry) * 10);
    (table->entries)[5].foo = 5;
    for (int i = 0; i < 10; i++) {
        printf("Entry #%d: %dn",i,(table->entries)[i].foo);
    }
}

首先,您需要在使用 malloc 时将 (void*) 类型转换为所需的指针类型。其次,你只分配条目指针,这意味着,当你使用(table->entryries)[5].foo 时,你可能会非法访问内存,所以这是一种危险的行为。最后,您需要在打印之前初始化foo。你需要遵守规则,不要写这样的代码。

相关内容

  • 没有找到相关文章

最新更新