c - 将结构传递给函数并将值存储在结构的元素中

标签 c arrays pointers memory-management malloc

我想将结构传递给函数并将值存储在结构的元素中。这是我的代码。

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

typedef struct {
    uint32_t len;
    uint16_t *arr;
} seq;

void write_seq(seq *q, int val)
{
    // How to implement this function?

    uint16_t *tmp;
    tmp = (uint16_t *)malloc(sizeof(uint16_t));
    *tmp = val;

    *(q->arr + q->len) = *tmp;
    q->len += 1;

}

int main(int argc, char *argv[])
{
    seq q;
    q.len = 0;
    q.arr = NULL;
    int i;
    for (i = 0; i < 10; i++) {
        write_seq(&q, i);
    }

    printf("length is %d\n", q.len);
    for (i = 0; i < q.len; i++) {
        printf("%d\n", *(q.arr+i));

    }

    return 0;
}

我想将 0 到 9 写入 q.arr 指向的内存块。
我不想在 main() 中使用 malloc,因为我不知道在调用 write_seq 之前我需要多少字节。每次调用 write_seq 时,我都想定位新内存。输出应该是这样的。

length is 10
0
1
2
3
4
5
6
7
8
9

我的 write_seq() 实现会导致核心转储。我不知道如何解决它。谢谢。

最佳答案

要在事先不知道数组大小时向数组添加成员,您需要使用 realloc() 来按需增加大小。但是,每次 更改数组大小时都这样做是低效的,因此更常见的做法是在缓冲区。

其必然结果是您需要存储缓冲区的当前容量以及当前使用量的偏移量。

这也意味着会有一定量的内存浪费,但这是您必须做出的权衡。

我的方法看起来像这样,将您可能希望在 seq 上执行的操作抽象化。

typedef struct {
    size_t    capacity;
    size_t    offset;
    uint16_t *arr;
} seq;

static const size_t SEQ_INITIAL = 8;
static const size_t SEQ_INCREMENT = 8;

int seq_init(seq *seq) {
    assert(seq != NULL);         /* catch null seq */
    assert(seq->arr == NULL);    /* error to call on already init'd seq */
    seq->capacity = SEQ_INITIAL;
    seq->offset = 0;
    seq->arr = malloc(seq->capacity * sizeof(seq->arr[0]));
    return seq->arr == NULL ? -1 : 0;
}

static int seq_grow(seq *seq) {  /* private implementation detail */
    size_t new_capacity = seq->capacity + SEQ_INCREMENT;
    void *p = realloc(seq->arr, new_capacity * sizeof(seq->arr[0]));
    if (p == NULL) {             /* realloc failed, seq unmodified */
        return -1;
    }
    seq->arr = p;
    seq->capacity = new_capacity;
    return 0;
}

int seq_write(seq *seq, uint16_t value) {
    assert(seq != NULL);         /* catch null seq */ 
    if ((seq->offset == seq->capacity) && seq_grow(seq) < 0) {
        return -1;               /* write failed */
    }
    assert(seq->arr != NULL);    /* catch bad seq */
    assert(seq->offset < seq->capacity); /* ensure seq really has room */
    seq->arr[seq->offset++] = value;
    return 0;
}

void seq_free(seq *seq) {
    if (seq != NULL) {
        free(seq->arr);
        seq->arr = NULL;
    }
}

关于c - 将结构传递给函数并将值存储在结构的元素中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46682738/

相关文章:

ios - 从数组中的值显示数组

c++ - 为什么使用数组会得到不同的结果?

c - 如何为void函数指针数组分配内存并为数组分配地址

c - 指针指针问题

c++ - C/C++ : Pointer on Pointer on structure

C 指针、空闲内存

c - DirectX 游戏的窗口 GUI 似乎有问题

java - Php 与 Java 数据库字符串比较

c - NUL——手工终止一个字符串

c - 错误 : Cannot convert 'char(*)[a]' to 'char(*)[2]' . 我不明白为什么会出现错误