【问题标题】:Will memory be allocated for a typedef structure pointer?是否会为 typedef 结构指针分配内存?
【发布时间】:2016-05-06 17:23:45
【问题描述】:

我有以下程序,其中我有一个结构。我将为它分配一些值并将其写入文件。 但这里的困惑是,我刚刚声明了一个指向该结构的指针并且没有分配内存。那么变量赋值是如何工作的呢? 我能够从文件“/home/info”中正确检索值

#include <stdio.h>
#define FILEE "/home/info"

typedef struct my_info
{
   int i;
   int j;
   int k;
   int l;
}_my_info;

void main()
{
    _my_info *my_info;
    int fd;
    FILE *fp;
    my_info->i=100;
    my_info->j=300;
    my_info->k=200;
    my_info->l=400;
    fp = fopen(FILEE,"w");
    if (fp == NULL)
        printf("Error in opening file\n");
    fd=fwrite(my_info, sizeof(_my_info), 1, fp);
    if (fd<0)
        printf("Error while writing\n");
    fclose(fp);
}

【问题讨论】:

  • 如果你写信给*my_info 而不先分配一些东西,这是未定义的行为。为什么你仍然需要一个指针?为什么不直接使用堆栈并声明_my_info my_info
  • 它不起作用。它只是看起来像是在工作。以后可能会中断。
  • 3 个注释; 1 - struct namespaceglobal namespace 是分开的,所以你可以做typedef struct my_info {...} my_info; 没有冲突,2,你也可以简单地声明一个typedef 到struct 单独@ 987654325@ 和 3,您可以简单地在代码中声明一个静态实例(例如 _my_info my_info; 并保留空间,然后您必须使用 dot 运算符(例如 my_info.i = 100; 等)
  • 请丢弃任何书籍或教程告诉你使用void main()。这是int main(void)。您检查fopen 是否成功,但如果失败则打印错误消息,然后继续访问该文件。
  • 未定义行为的行为未定义。

标签: c memory dynamic-memory-allocation


【解决方案1】:

您当前的代码存在几个问题。在遇到结构问题之前,您似乎将writefwrite 的返回值与:

fd=fwrite(my_info, sizeof(_my_info), 1, fp);
if (fd<0)
    printf("Error while writing\n");

fwrite 返回值为size_t 类型。它永远不会小于0。如果您使用 warnings-enabled 进行编译(例如 -Wall -Wextra),您将始终收到关于比较始终测试为 false 的警告。

关于你的结构空间,你为什么要声明一个指针?除非您在示例中声明指针有某些压倒一切的原因,否则只需声明结构的静态实例,以便自动保留存储空间。如果你确实声明了一个指针,那么你必须分配空间(例如 _my_info *my_info = malloc (sizeof *my_info);_my_info *my_info = calloc (1, sizeof *my_info);

对于您的示例,除了进行动态分配之外,没有理由声明指针,只需声明一个实例即可。以下是使用实例和从文件写入/读取值的简短示例。 (注意: 关于 int main() 的 cmets 以及将默认文件名更改为 /tmp/info.bin):

#include <stdio.h>

#define FILEE "/tmp/info.bin"

typedef struct {
    int i;
    int j;
    int k;
    int l;
} _my_info;

/* main is type 'int', has arguments and returns a value */ 
int main (int argc, char **argv)
{
    _my_info my_info, my_info2; /* static instances */
    /* write to given filename, or FILEE (default)  */
    FILE *fp = fopen (argc > 1 ? argv[1] : FILEE, "wb");

    if (!fp) {
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    my_info.i = 100;
    my_info.j = 300;
    my_info.k = 200;
    my_info.l = 400;

    if (fwrite (&my_info, sizeof my_info, 1, fp) < 1) {
        fprintf (stderr, "error: write to '%s' failed\n",
                argc > 1 ? argv[1] : FILEE);
        return 1;
    }
    if (fclose(fp) == EOF) goto errclose;

    printf ("\n values written to : %s\n", argc > 1 ? argv[1] : FILEE);

    /* reopen file for reading, read values into my_info2 */
    fp = fopen (argc > 1 ? argv[1] : FILEE, "rb");
    if (fread (&my_info2, sizeof my_info2, 1, fp) < 1) {
        fprintf (stderr, "error: read from '%s' failed\n",
                argc > 1 ? argv[1] : FILEE);
        return 1;
    }

    if (fclose(fp) == EOF) goto errclose;

    printf (" values read from  : %s\n\n", argc > 1 ? argv[1] : FILEE);
    printf ("  my_info2.i : %d\n  my_info2.j : %d\n"
            "  my_info2.k : %d\n  my_info2.l : %d\n\n",
            my_info2.i, my_info2.j, my_info2.k, my_info2.l);

    return 0;

  errclose:
    fprintf (stderr, "error: EOF returned on stream close.\n");
    return 1;
}

输出

$ ./bin/struct_write

 values written to : /tmp/info.bin
 values read from  : /tmp/info.bin

  my_info2.i : 100
  my_info2.j : 300
  my_info2.k : 200
  my_info2.l : 400

如果您还有其他问题,请告诉我,如果您迫切需要使用指向结构的指针,请告诉我,我很乐意为您提供进一步帮助。

【讨论】:

  • 感谢您的评论 David。我只是想知道指向结构的指针是如何工作的。
  • 当然,希望对您有所帮助。简而言之,在处理结构时,您只需确定“我有结构或指向结构的指针吗?”如果你有一个结构,那么你使用'.' 运算符来访问成员,使用指针,你使用'-&gt;' 运算符。如果您有一个结构并获取该结构的地址(例如&amp;structname),那么您就有一个指向 structname 的指针。如果您声明一个结构,您将获得自动内存管理,使用指针,由您分配:)
【解决方案2】:

当你声明my_info

_my_info *my_info;

它将有一个 undefined 值。在您的情况下,my_info 的值在 RAM 的有效内存地址范围内。因此,将对其进行写入和读取。

但是,您不知道因此而更改了其他哪些内存。这可能会导致内存损坏,尤其是在较大的程序中。

【讨论】:

    【解决方案3】:

    由于你没有初始化指针变量,它的值是随机的,意味着指针指向某个随机地址。 访问地址时,根据您的操作系统,它可能会崩溃,或者只是得到一些垃圾数据。

    【讨论】:

      【解决方案4】:

      由于my_info 指针存在于堆栈中,因此很可能之前使用了相同的位置并指向一些分配的内存。您正在覆盖一些其他数据,这可能会也可能不会导致您的程序崩溃。

      简而言之-它是偶然起作用的。

      【讨论】:

        猜你喜欢
        • 2019-09-23
        • 1970-01-01
        • 1970-01-01
        • 2017-05-07
        • 2017-07-28
        • 1970-01-01
        • 2023-04-02
        • 2017-01-03
        • 2021-05-07
        相关资源
        最近更新 更多