在结构

时间:2018-03-23 23:45:34

标签: c struct

假设我有以下内容:

#include <stdio.h>

typedef struct
{
    int num;
} myObj;

typedef struct
{
    myObj *obj_ptr;
} myStruct;

void populate(myStruct *m1)
{
    m1->obj_ptr->num = 123;
}

int main()
{
    printf("Hello World");
    myStruct m1;
    populate(&m1);

    printf("%d", m1.obj_ptr->num);

    return 0;
}

此代码的目的是我想获得一个项目,例如m1填充populate而不是m1.obj_ptr->num函数返回,因此编码方式。

我关注public class Node { int value; Node next; public Node() { } public Node(int c) { this.value = c; } public boolean hasNext() { if (next == null) { return false; } else { return true; } } 这一行,因为它似乎不是一个好的设计。即使我运行它,这段代码是否有任何问题?有更好的方法吗?

2 个答案:

答案 0 :(得分:4)

在结构中有一个指针是可以的,但是你必须为它分配内存:

void populate(myStruct *m1)
{
    m1->obj_ptr->num = 123;
}

错误,因为m1->obj_ptr未初始化。你可以这样做:

void populate(myStruct *m1)
{
    // always check for validity of arguments
    if(m1 == NULL)
        return;

    m1->obj_ptr = malloc(sizeof *m1->obj_ptr);
    if(m1->obj_ptr == NULL)
        return;

    m1->obj_ptr->num = 123;
}

我个人会让populate成功返回1,失败则返回0 调用者知道分配是否成功。

但你不必忘记释放记忆:

int main()
{
    printf("Hello World");
    myStruct m1;
    populate(&m1);

    if(m1.obj_ptr)
        printf("%d", m1.obj_ptr->num);

    free(m1.obj_ptr);

    return 0;
}

如果你说,你不想在populate中分配内存,那么你必须这样做 在调用populate之前初始化指针,如下所示:

int main()
{
    printf("Hello World");
    myStruct m1;
    myObj obj;

    m1.obj_ptr = &obj;

    populate(&m1);

    printf("%d", m1.obj_ptr->num);

    return 0;
}

但是这样做的缺点是你不能将这个结构返回给另一个结构 功能。这是不正确的:

myStruct get_me_a_struct(void)
{
    myStruct m1;
    myObj obj;

    m1.obj_ptr = &obj;

    populate(&m1);

    return m1;
}

void foo(void)
{
    myStruct m2 = get_me_a_struct();

    printf("%d\n", m2.obj_ptr->num); // <-- you cannot do that
}

因为m2.obj_ptr会指向无效的位置。出于这个原因,使用 malloc用于分配更好。

答案 1 :(得分:1)

两件事;都在populate()内:

首先,您无法在代码中为obj_ptr分配或取消分配空间。您只需在其中设置num的值,并希望获得最佳效果。在行m1->obj_ptr->num = 123;123 m1->obj_ptr = malloc(sizeof(myObj))分配一些内存之前,num。如果没有这个,当你设置populate()时,它实际上是指向一个未知的内存地址,这可能不会留给你的程序使用。

同样,m1在分配给其成员之前不会检查populate()是否为有效地址。在这个示例代码中,它(仅大部分)是正常的,因为当您调用&时,您传递的是引用(*)而不是指针(populate()),但是,如果您你将来可能会用指针调用它。实际上,if(m1 != NULL)中的第一行需要{{1}},其余部分都在里面。