RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 993151
Accepted
bylochka
bylochka
Asked:2020-06-16 02:53:07 +0000 UTC2020-06-16 02:53:07 +0000 UTC 2020-06-16 02:53:07 +0000 UTC

两种分配内存方式的区别不清楚

  • 772

伙计们,我不明白这两种分配内存的方法有什么区别,第一种方法在我看来要清楚得多。为什么在第二种方法中必须使用结构指针运算符(->),而第一种方法中只有一个点?-> 用于需要访问指针变量所引用的结构的数据时,那么在第一种方法中也需要使用->,而不是点。请解释一下,我真的不明白。

1种方式:

#include <stdio.h>
#include <stdlib.h>
struct BooksInfo
{
    char name[50];
    char author[50];
    int pages;
    int year;
};
int main (void)
{
    int ctr,quantily;
    puts("Сколько книг вы хотите заполнить? ");
    scanf (" %d", &quantily);
    getchar();
    struct BooksInfo *books;
 books=(struct BooksInfo*) malloc(quantily*sizeof(struct BooksInfo));
    for (ctr=0;ctr<quantily;ctr++)
    {
        puts ("Какое название у книги? ");
        scanf("%s",books[ctr].name);
        puts ("Какой автор книги? ");
        scanf("%s",books[ctr].author);
        puts ("Сколько страниц в книге? ");
        scanf("%d",&books[ctr].pages);
        puts ("Какого года книжка? ");
        scanf("%d",&books[ctr].year);
    }


    return 0 ;
}

第二种方式:

#include <stdio.h>
#include <stdlib.h>
struct BooksInfo
{
    char name[50];
    char author[50];
    int pages;
    int year;
};
int main (void)
{
    int ctr,quantily;
    puts("Сколько книг вы хотите заполнить? ");
    scanf (" %d", &quantily);
    getchar();
    struct BooksInfo *books[quantily];
    for (ctr=0;ctr<quantily;ctr++)
    {
     books[ctr]=(struct BooksInfo*) malloc(sizeof(struct BooksInfo));
        puts ("Какое название у книги? ");
        scanf("%s",books[ctr]->name);
        puts ("Какой автор книги? ");
        scanf("%s",books[ctr]->author);
        puts ("Сколько страниц в книге? ");
        scanf("%d",&books[ctr]->pages);
        puts ("Какого года книжка? ");
        scanf("%d",&books[ctr]->year);
    }


    return 0 ;
}

是的,我知道您需要检查动态内存的分配并清理它。

我是否正确理解这两种方法的工作原理? 在此处输入图像描述

2:在此处输入图像描述

我稍微更正了代码,即在分配内存时删除了星号

c
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. KoVadim
    2020-06-16T03:07:34Z2020-06-16T03:07:34Z

    在第一种情况下,分配了一大块内存并将整个对象数组放置在其中。不错,可靠的方法。删除是一个电话free。由于放置了一组结构,因此访问一个元素就是一个点。

    在第二种情况下,首先创建一个指向结构的指针数组。但它使用VLA。但由于代码很糟糕,没关系。然后为每个结构分配内存。在 gamedev 中,他们真的不喜欢这样 - 有太多的小对象。另外,必须仔细编写发布代码。

    在第二种情况下,指向结构的指针存储在数组中。这就是为什么你需要使用箭头。或者通过显式取消引用*,然后就可以使用一个点。

    • 2
  2. Best Answer
    alexanius
    2020-06-16T19:54:19Z2020-06-16T19:54:19Z

    让我们从操作.和开始->。访问结构元素的操作.放在结构对象和字段名之间:str.field. 在使用指向结构的指针时,字段引用应该是这样写的:(*str_ptr).field,但是这种方法不是很清楚,操作很常见。因此,他们把它变成了同义词——操作->:。str_ptr->field

    更多关于内存分配。这两个示例使用两个不同的内存区域。让我们从使用数组的第二个示例开始。视图构造为堆栈int a[N]上的数组提供空间。堆栈内存是过程的所有临时对象的内存。进入程序时自动分配,程序结束时自动清除。但这里有个窍门。在示例中,它是一个变量,即 数组的大小事先不知道。这是添加到 C99 标准的可变长度数组 (VLA) 的一个例子。对于这样的数组,内存不是在过程入口处分配,而是在数组声明处分配。N

    在第一种情况下,使用了在堆上malloc分配内存的过程。堆是仅由程序员控制的动态内存区域。因此,程序完成后,通过分配的内存将存活并可以访问。该操作用于清除此类内存。mallocfree

    现在让我们继续看具体的例子。考虑第一个例子:

    books=(struct BooksInfo*) malloc(quantily*sizeof(struct BooksInfo*));
    

    在这里,我们分配了一块内存,其中包含quantily指向该结构的指针BooksInfo。从这一段内存的进一步使用来看,其实是这样的构造:

    books=(struct BooksInfo*) malloc(quantily*sizeof(struct BooksInfo));
    

    现在这个内存区域包含quantily类型的对象BooksInfo。当使用数组元素访问操作时,[]我们指的是括号内给出的元素。那。构造books[ctr]将产生一个类型为 的对象BooksInfo。正如我们已经知道的那样,要访问结构的字段,使用了操作.,它是这样做的:books[ctr].name。

    现在考虑构造

    struct BooksInfo *books[quantily];
    

    这里我们说一个对象books是一个指向结构的指针数组BooksInfo。但是我们需要使用对象,所以在循环中我们为每个指针分配内存:

    books[ctr]=(struct BooksInfo*) malloc(sizeof(struct BooksInfo*));
    

    现在考虑构造的结果books[ctr]。我们记得数组包含指向结构的指针,所以我们会得到一个类型为 的对象BooksInfo *。要引用结构指向的对象的字段,请使用操作->.

    UPD

    您可以(*).在这篇文章中了解操作的历史差异,感谢@Croessmah 的评论->

    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5