【问题标题】:Using pointers and structs使用指针和结构
【发布时间】:2010-12-20 17:07:07
【问题描述】:

您好,我不确定我是否理解以下代码。如果有人可以阅读我的解释并在我错了时纠正我,我会很高兴。
所以首先我要声明一个结构,其中包含三个 char 数组和一个整数。

struct Employee 
{
    char last[16];
    char first[11];
    char title[16];
    int salary; 
};


之后,我声明了一个函数,该函数接受三个指向 char 的指针和一个整数值。此函数使用 malloc() 和 sizeof() 在堆上创建结构。现在,我在堆上创建的对象并不是很清楚。当我使用 struct Employee* p = malloc(sizeof(struct Employee)) 时,那里会发生什么确切地
当我使用函数 struct Employee* createEmployee (char* last, char* first, char* title, int salary) 多次使用不同的输入时会发生什么。我知道我会得到一个指针 p 但不是指向堆上同一个结构的同一个指针。那么当我多次使用该函数时,我是否要重写堆上的信息?还是它总是在不同的内存空间中创建一个新对象?

struct Employee* createEmployee(char*, char*, char*, int);

struct Employee* createEmployee(char* last, char* first, char* title, int salary)  
{
    struct Employee* p = malloc(sizeof(struct Employee));
    if (p != NULL) 
    {
        strcpy(p->last, last);
        strcpy(p->first, first);
        strcpy(p->title, title);
        p->salary = salary;
    }
    return p; 
}

如果有人可以向我解释,我会很高兴。非常感谢。

【问题讨论】:

  • 这是作业吗?如果是的话,请把它标记为这样,以便家庭作业精灵可以轻松找到它。
  • 不,这不是家庭作业。我正在尝试自学 C。
  • 我认为最好使用枚举来表示员工的头衔,而不是字符串。通过位移,这也允许多个标题。但是,这只是一个想法,稍后您将在 C 学习课程中遇到这个问题。 :)

标签: c


【解决方案1】:

malloc 函数在堆上分配一些新字节并返回指针。

所以createEmployee 函数每次调用时都会分配新内存,然后用一些数据填充它(以不安全的方式 - 考虑改用strncpy 并返回指向该内存的指针.每次调用它都会返回一个不同的指针。

只要您不在其指针上调用free,您使用此函数创建的每个实例都会存在。

【讨论】:

  • 谢谢,这让我更清楚了。我还有一个关于前缀“struct Employee*”的问题。这似乎意味着该函数返回的值是一个指向具有原始结构 Employee 的“形式”的结构的指针。对吗?
  • 没有“原始”结构 Employee。从“struct Employee {”到“};”的代码不创造价值;它定义了一个类型。它的目的是说“这就是'Employee'结构”。然后createEmployee() 分配足够的空间来存储一个Employee 结构体,将相关数据放入该空间,并返回一个指向新创建的Employee 的指针。
【解决方案2】:

您的第一个问题是关于 malloc 的问题。搜索“malloc 如何工作?”可能会得到更好的结果。对于不同的操作系统和 C 库,答案是不同的。

createEmployee 函数每次调用都会创建一个全新的结构 Employee。

我还看到 createEmployee 的编写方式非常危险。在调用 strcpy 之前,不进行任何检查以确保字符串适合其目的地。这就是缓冲区溢出的产生方式。

【讨论】:

    【解决方案3】:

    malloc 为您分配一个与其第一个参数相等的内存块,在本例中为 Employee 的大小。

    每次拨打createEmployee,您都会单独拨打一次malloc,每次拨打malloc,都会给您一段新的记忆。

    这就是允许您拥有不同员工的原因:如果他们都使用相同的内存,您将只能创建一个。

    这就是为什么调用free 并释放内存很重要:操作系统无法知道您是否正在使用内存。

    如果您想编辑现有的employee,请维护对其的指针引用,并添加strcpy(p->title, newTitle); 以将其标题更改为newTitle。

    另外,已经提到的东西,strcpy 是危险的,因为它会继续写它的字符串,不管它是否超过了分配给它的 11 个字符。

    【讨论】:

      【解决方案4】:

      每次您拨打malloc() 时,您都在告诉它为您提供一块新的内存,至少在您要求的时候是这样,目前在其他任何地方都没有使用。所以下面给你三个不同的指针:

      void *p1 = malloc(100);
      void *p2 = malloc(100);
      void *p3 = malloc(100);
      

      这就像在自动售货机上按下按钮一样。每次,您都会得到符合您要求的不同糖果棒(例如“Caramilk”)。

      【讨论】:

        猜你喜欢
        • 2020-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-19
        • 2015-07-10
        • 1970-01-01
        • 1970-01-01
        • 2013-02-15
        相关资源
        最近更新 更多