【问题标题】:C malloc(1) with structure working [duplicate]C malloc(1)与结构工作[重复]
【发布时间】:2016-02-27 06:41:15
【问题描述】:

我实际上是在学习 C 并且遇到了一个“问题”。

我用 char* 和 malloc(1) 创建了一个指向结构的指针。 指针有效,我可以毫无问题地编辑结构子项。

我还创建了一个指向 int 的指针(仍然使用 malloc(1))并且它可以工作。另一件事是当我尝试访问 *(pointer + 33780) 时没有收到核心转储错误(当值稍高时会出现核心转储)它有效,但默认值为 0。

谢谢,这不是“问题”,但我想知道为什么会这样。

很抱歉成为英国的凶手。

编辑:这里是代码

struct Personne
{
  char *name;
  int age;
};

int main(int argc, char *argv[])
{
    printf("%ld\n", sizeof(struct Personne));
    struct Personne *testPoint = malloc(1);
    printf("testPoint : %p\n", testPoint);
    printf("testPoint : %p\n", testPoint->name);
    testPoint->name = "UnNomInconnu";
    testPoint->age = 20;

    free(testPoint);
    return 0;
}

【问题讨论】:

  • 您确实应该显示实际代码。但请理解:如果您访问应用程序有效内存空间之外的内存,您可能会也可能不会遇到分段错误或任何其他错误。没有错误并不表示代码中没有问题。您可能已经访问了目前不会造成任何不良影响的远程内存。在这种malloc 的特殊情况下,它可能是内存堆中属于另一个进程的某个其他位置,或者仍然可供另一个进程(或您的进程)分配。这将是无效的访问。
  • 您正在调用未定义的行为,因为您正在访问尚未正确分配的内存,使用不同类型的指针等等等。未定义的行为意味着任何事情都可能发生,例如崩溃,但它也可以是其他任何东西——程序甚至可以完成执行并产生正确的结果。
  • 两个小问题:使用printf("%zu\n", sizeof(struct Personne));和使用printf("testPoint : %p\n", (void*)testPoint);
  • 确实应该有一个规范的重复问题,用于询问为什么他们在做他们知道是无效的事情时没有得到错误的所有问题。

标签: c pointers struct malloc


【解决方案1】:

实际上,函数 malloc 并没有分配 1 字节大小或类似小值的内存范围。通常分配范围的最小大小等于段落的大小,即 16 字节。

所以如果你会写例如

char *p = malloc( 1 );

那么分配的extent的实际大小可以等于16字节。

尽管如此,您不应依赖此功能,因为根据 C 标准,这是未定义的行为。

【讨论】:

  • 谢谢,我试过printf("%ld\n", sizeof(*testPoint));,它打印了我16个字节,问题解决了。
  • @Juju17ification 你得出了错误的结论。:) 这个表达式 sizeof(*testPoint) 未计算。只需您的结构大小等于 16 个字节。它不是分配范围的大小。:)
  • 好吧,我相信你所分配的内存大小会大于 1(如果我理解正确的话)。
  • @Juju17ification 你理解正确。尽管如此,在任何情况下,您都可能不会这样做,因为通常这是未定义的行为。该标准没有说当范围的实际大小。它只是说您将获得所需大小的内存。
【解决方案2】:

你需要:

struct Personne *testPoint = malloc(sizeof(*testPoint));

1 字节的内存不足以容纳您的结构。 malloc() 参数的含义是字节数。但是,malloc() 并不一定会保护已分配段之外的内存,因此在某些情况下可以覆盖边界而不会造成致命后果。

【讨论】:

  • 我认为 OP 抱怨它在使用上述(显然不正确)代码时没有崩溃。
  • 我认为 OP 意识到了这一点;他们问为什么使用1 作为论据仍然给了他们看似正确的行为。
【解决方案3】:
 struct Personne *testPoint = malloc(1);

将您带入未定义行为的领域。不幸的是,UB 可以包含“程序在所有测试环境中都能正确运行,但在最坏的可能时间在生产中失败”——而且经常这样做。

如果您使用的是 linux,请在 valgrind 和/或电子围栏下运行您的程序。您将看到这些工具存在的原因。

【讨论】:

    猜你喜欢
    • 2012-10-02
    • 1970-01-01
    • 2017-10-03
    • 2011-06-15
    • 2017-02-22
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多