malloc() 和 realloc() 结构

Posted

技术标签:

【中文标题】malloc() 和 realloc() 结构【英文标题】:malloc() and realloc() of structures 【发布时间】:2021-01-15 08:25:23 【问题描述】:

我们可以为结构动态分配内存吗?这是处理动态分配结构的正确程序吗?请告诉我如何malloc()realloc() 一个结构。

newnode 是 struct List * 类型,但是在开始索引时它会转换为 struct List。这种转换如何可能?我的插入函数只接受 (struct List*) 我在某处错了吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct List 
    char val[20];
;

void insert(struct List *);

int main(void) 
    int i = 0;
    int size = 1;
    struct List *newnode = (struct List *)malloc(size * sizeof(struct List));
    for (i = 0; i < 5; i++) 
        if (size <= i) 
            size = size + size;
            newnode = (struct List *)realloc(newnode, size * sizeof(struct List));
        
        scanf("%s", newnode[i].val);
        insert(newnode[i]);
    
    for (i = 0; i < 5; i++) 
        printf("%s\n", newnode[i].val);
    
    return 0;


void insert(struct List *node) 
    printf("%s\n", node->val);

【问题讨论】:

它可以编译吗? -> 它没有。 realloc 的处理是错误的,如果 realloc 失败,你也会丢失原始数组...... 为什么relloc 错了 什么是正确的实现方式? 见这里:***.com/q/38213123/10871073 和这里:***.com/q/605845/10871073 "这是一个正确的过程吗" --> 最后缺少free() 感谢您的快速回复......还有一个问题,newnode 的类型是 struct List * 但是当开始索引时它会转换为 struct List。这种转换如何可能?我的插入函数只接受(struct列表*) 我是不是哪里错了? 【参考方案1】:

是的,这很好,只是您将返回值分配给原始数组指针。 realloc() 如果无法调整内存大小,则返回 NULL。您需要将其分配给一个临时变量,如果值为NULL,请不要覆盖a

您需要注意的主要事情是指针,而您的struct 没有。在这些情况下,指向的内存不是分配数组的一部分。

【讨论】:

【参考方案2】:

除了 3 个问题之外,代码可以正常工作:

您不测试内存分配失败。如果无法分配内存,malloc()realloc() 都将返回 NULL:如果发生这种情况,在取消引用 newnode 时会出现未定义的行为。

要优雅地处理realloc() 失败的情况,您应该将重新分配的指针存储到不同的变量,以便您仍然可以访问尚未释放的前一个数组并释放它。

scanf("%s", newnode[i].val); 是一个安全漏洞:您应该限制可以存储到目标数组的字节数

scanf("%19s", newnode[i].val);

您没有测试scanf() 的返回值来检测无效或丢失的输入。

insert() 没有插入任何东西。

这里是一个修改后的版本,带有错误处理和较少混淆的名称:

#include <stdio.h>
#include <stdlib.h>

struct Item 
    char val[20];
;

//void insert(struct Item *);

int main(void) 
    int i, j;
    int size = 0;
    struct Item *array = NULL;
    for (i = 0; i < 5; i++) 
        if (i >= size) 
            int newsize = size ? 1 : size + size;
            struct Item *newarray = realloc(array, sizeof(*array) * size);
            if (newarray == NULL) 
                perror("cannot reallocate the array");
                break;
            
            size = newsize;
            array = newarray;
        
        if (scanf("%19s", array[i].val) != 1) 
            fprintf(stderr, "missing input\n");
            break;
        
        //insert(array[i]);
    
    for (j = 0; j < i; i++) 
        printf("%s\n", array[i].val);
    
    free(array);
    return 0;

【讨论】:

IDK,也许是为了开始这样有趣的对话? (社会工程机器人);-) IAC,我会使用struct List *newnode = realloc(node, sizeof *node * size); 甚至void *newnode = realloc(node, sizeof *node * size);。很多方式都可以接受。 @chux-ReinstateMonica:很好的建议,但为了避免一元和二元* 的组合有些混乱,我更喜欢使用多余的括号并写成void *newnode = realloc(node, sizeof(*node) * size); 它不是列表,只是结构数组。 @P__J__:我同意struct标签和变量名的选择相当混乱。

以上是关于malloc() 和 realloc() 结构的主要内容,如果未能解决你的问题,请参考以下文章

alloc()malloc()calloc()realloc()区别及用法

C:malloc/calloc/realloc/alloca内存分配函数

堆的分配和释放(malloc,free,calloc,realloc)

C语言复习之malloc和realloc(为字符串数组分配内存)

malloc realloc calloc的区别

realloc ------ 扩大malloc得到的内存空间