使用带双指针的struct及其内存构成

使用带双指针的struct及其内存构成,c,pointers,struct,C,Pointers,Struct,我编写了这段代码,其中我分配了一个结构,然后为结构释放了内存: struct item { int val; int *vectOfInt; struct item *next; }; void relItem(struct item **currItem) { struct item *temp; int *intTemp; temp = *currItem; intTemp = (*currItem)->vectOfInt;

我编写了这段代码,其中我分配了一个结构,然后为结构释放了内存:

struct item {
    int val;
    int *vectOfInt;
    struct item *next;
};

void relItem(struct item **currItem) {
    struct item *temp;
    int *intTemp;

    temp = *currItem;
    intTemp = (*currItem)->vectOfInt;
    *currItem = (*currItem)->next;
    free(temp);
    free(intTemp);
}

int main() {
    int array[] = {0, 1, 2, 3, 4, 5};
    struct item *list = NULL;

    list = (struct item*) malloc(sizeof(struct item));
    list->val = 0;
    list->vectOfInt = array;
    list->next = NULL;

    relItem(&list);

    return 0;
}
编辑:注释的代码:

struct item {
    int val;
    struct item *next;
};

void edit(struct item *currItem) {
    currItem->val = 2;
}

int main() {
    struct item *list = NULL;
    list = (struct item*) malloc(sizeof(struct item));
    list->val = 0;
    list->next = NULL;

    edit(list);

    //list-val == 2

    return 0;
}
  • 如何在不使用指向结构的双指针的情况下执行相同的操作?

  • 你能给我解释一下为什么要这样做,以及它是如何工作的(包括指针和双指针)?

  • 我不明白一个结构是如何在主内存中表示的 (例如
    inta[5]
    ;内存中的a是指向为
    a[5]
    数组分配的缓冲区的第一个位置的指针)

用ha指针初始化的结构的相等表示法是什么
(结构项*s)

  • 如果您想在不同的函数中更改
    列表的值,您必须给出它的地址,因为C中的所有参数都是通过值传递的,而不是通过引用传递的
  • 您将地址指定给指针,因为您想更改指针
  • INTA[5]不是结构,而是数组,结构和数组在C中表示为内存块。当您引用结构的成员时,实际上是指与结构位置的偏移
  • A.如果不是在堆上(使用malloc)而是在堆栈上分配(
    int-array[]={0,1,2,3,4,5};
    -本地分配),则释放
    vertorOfInts
    ,这是无效的,并且会使程序(可能)崩溃

    如果不使用指向结构的双指针,我如何做同样的事情? 你必须使用双指针

    你能给我解释一下为什么和如何工作(包括指针和双指针)? 双指针是必需的。数据结构是指向结构的指针。然后调用需要修改该指针的函数。由于参数是按值传递的,所以必须向指针传递指针

    我不明白一个结构是如何在主内存中表示的。
    通常,结构按顺序排列。因此,第一个成员将被放置在为结构保留的内存的开头,第二个成员将跟随它,依此类推。还有填充和对齐的问题,但这有点复杂,最好留给编译器处理。

    您可以这样想:您的数据结构是一个单链接列表,其中每个节点的类型都是
    T=struct item*
    。您通过列表的头部(即第一个节点)传递列表。消费者可以通过查看
    T来浏览整个列表。next
    ,值
    NULL
    表示您已到了末尾


    函数
    relItem
    从列表中删除第一个节点。由于它操纵列表本身,您必须向它传递一个指向列表头的指针,即
    T*
    ,即
    struct item**
    。最后,
    T=NULL
    将被解释(并检查!)为没有节点的空列表。

    此代码无需双指针即可安全运行:

    无效重新项(结构项*当前项) {…}

    用relItem(列表)调用它

    释放指针不会更改其值。 将双指针作为参数的函数通常用于更改指针(例如,分配指针或使其为NULL)


    只要在空闲时小心(intTemp),它会崩溃,因为你正在从堆栈中释放内存。

    -p>你需要使用双指针,因为你需要更改指向结构的指针,而C中不允许通过引用调用

    -它不能使用单个指针。因为您想更改指向对象的指针。通过语句
    *currItem=(*currItem)->next
    为了永久地更改它,您需要使用指向它的指针。这使得您使用双指针

    这样想吧:

    您有一个整型变量
    a
    ,希望函数更改其值。您只需使用指向变量
    a
    比如:

    在您的例子中,您希望更改指针的值,只需将其指针传递给函数即可。(双指针) 就这么简单如果要使用函数更改某个对象的值,则必须将其指针传递给该函数。

    -当你打电话给malloc时,你需要它的空间。你说你想要一个和你的结构一样大的空间。(就像你在这里做的那样,
    list=(struct item*)malloc(sizeof(struct item));
    )和malloc分配一个和你的结构一样大的空间。若结构的大小是1字节,那个么你们有一个1字节的空间,若它是4字节,那个么你们有连续的4字节。 看,这就是结构在内存中的保存方式。 如果您声明一个结构变量或数组等,那么您的结构会像数组一样保存在内存中。第一个成员先来,然后第二个

    如果你有一个结构

    struct myStruct
    {
        int a;
        float b;
        char c;
    };
    
    然后记忆看起来像


    a


    b


    c


    ps:您在线路
    free(intTemp)上非法呼叫free您正在*释放*一个未*malloc*编辑的变量。

    您尝试过吗?它甚至不应该工作,因为您正在对
    free()
    进行非法调用。
    vectOfInt
    的值是指向自动变量的指针,
    malloc()
    尚未获取该值。当你说
    free(intTemp)
    时,你是在该指针上调用
    free()
    ,这是非法的。你怎么能说它没有错误?您的代码没有检查错误。@David:这一点很好-由于该结构在不同的位置使用了
    NULL
    来传达事情的结局,因此您必须在代码的不同位置检查它!(我在回答中也提到了这一点。)OP:“没有崩溃”:你运行代码了吗?@frx08“没有编译器错误和崩溃”哦,天哪。恐怕除了这个还有很多要检查的!谢谢
    struct myStruct
    {
        int a;
        float b;
        char c;
    };