【问题标题】:array pointers to structures指向结构的数组指针
【发布时间】:2016-05-17 19:08:33
【问题描述】:

我写了这个程序:

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

struct inventory{
    int ID;
    char name[20];
    int value;
};


int main()
{
    struct inventory *inv;

    inv = malloc(sizeof(1));

    inv[0].ID = 10;
    strcpy(inv[0].name,"hello charlie old mate");
    inv[0].value = 20;

    inv[1].ID = 20;

    printf("%d", inv[1].ID);

    return 0;
   }

你能告诉我如何将inv[1].ID 设置为 20。当我为inv 分配仅 1 字节的内存时。它如何承载多种结构的数据?

【问题讨论】:

  • 你听说过未定义的行为吗?
  • “当我只为 inv 分配 1 个字节的内存时。”是错误的。分配的代码sizeof(1) 字节肯定不是 1,但更可能是 4。
  • 只是为了详细说明@chux sir 所说的,sizeof 考虑的是数据类型,而不是 ,文字 1 的类型是 int。 :)
  • “我支付了一个停车位,但后来我在那个停车位和一些相邻的停车位上停了很多车。怎么可能?我只付了一个停车位。”
  • @ThomasPadron-McCarthy 让我知道你明天早上是否能在那里找到你的车。 :)

标签: c arrays pointers structure


【解决方案1】:

您的代码中有未定义的行为 -

inv = malloc(sizeof(1));      // you allocate size of int
inv[0].ID = 10;
strcpy(inv[0].name,"hello charlie old mate");    //copying more than your buffer can hold

您分配的大小等于int 的大小,不足以构造和访问未经授权的内存。然后strcpy,您尝试存储的内容多于可用空间。 name 可以在末尾包含 19 字符和 '\0'。并且您复制的字符串大于19 个字符。

【讨论】:

    【解决方案2】:

    你能告诉我如何将 inv[1].ID 设置为 20。当我只为 inv 分配 1 个字节的内存时。怎么能承载多种结构的数据?

    TL;DR不能。

    您看到的是调用undefined behavior 的无效内存访问。 C 标准中没有任何内容可以阻止您编写访问无效内存的代码,但是一旦您这样做,瞧!!

    分配给inv(通过调用malloc(1))的内存少了。因此,基本上,您正在尝试访问不属于您(您的进程)的内存,因此该内存无效。任何访问无效内存的尝试都会导致 UB。

    遵循相同的路径,即使您已为 inv 分配了适当的内存,然后也

     strcpy(inv[0].name,"hello charlie old mate");
    

    将是 UB,因为您尝试将多个 20 元素复制到大小仅为 20 的目标中(如果您希望 name 成为 19 个有效的 chars + 1 个空终止符,用作字符串)。正确计算您的内存需求并保持在界限内。

    也就是说,在使用返回的指针之前,请始终检查 malloc() 的返回值是否成功。

    【讨论】:

    • 我知道你的意思我喊 allocate inv = malloc(sizeof(struct inventory));因此,它应该使指针仅访问一个结构 inv[0],尽管即使我向 inv[1],(...) inv[5] 添加更多内容,它也会编译并给出一些奇怪的答案。用prtscr查看我的评论
    • @FenixxReborn 是的,或者。为了更好,inv = malloc(sizeof *inv);
    • @FenixxReborn 对于已编辑的部分,您必须知道分配的大小并相应地访问。同样,C 不会阻止您访问 inv[5],而您只分配了 1 个元素,但它会导致 UB。
    • 我只为某些结构部分添加了值。它将 0 附加到所有这些。无需任何初始化。这很奇怪,完全不明白。因为我认为应该有垃圾? UB 通过访问此内存不会产生不好的结果。但是,当我在我的程序中创建更多有效数据时,它可能会被它占用,对吧?所以最后,当我想创建一个指向结构的有效指针数组时,我应该通过 n * sizeof(struct inventory) 重新分配它们,然后我可以通过调用 inv[1] 和 inv[2] 来调用它们。我说的对吗?
    • @FenixxReborn 基本上是的。但请记住,malloc() 返回未初始化的内存,内容不确定。是的,0 是一个非常垃圾的值(在这种情况下),就像 4537921636-62490936
    猜你喜欢
    • 1970-01-01
    • 2017-06-03
    • 2012-12-07
    • 2016-06-20
    • 1970-01-01
    相关资源
    最近更新 更多