我需要一个通用函数,将值放入数组中,我是这样写的:

int add_element(void** arr, void* val, int t_size, int* size, int* capacity) {

    if ((*size) == (*capacity)) {
        *capacity += ARRAY_INC;
        *arr = (char*)realloc(*arr, (*capacity) * sizeof(char));

        if (*arr == NULL) {
            return 1;
        }
    }

    memcpy(*arr + ((*size)++), val, t_size);

    return 0;
}

它非常适合char数组,但我在下一段代码中遇到了结构数组的问题:
int scan_tokens(Token** p_tokens, int* size) {
    char* line;
    int len;

    if (get_line(&line, &len)) {
        return 1;
    }

    int capacity = ARRAY_INC;
    *size = 0;
    *p_tokens = (Token*)malloc(capacity * sizeof(Token));
    int start = -1;

    for (int i = 0; i < len; ++i) {
        char ch = line[i];

        if (isdigit(ch)) {

            if(start == -1) {
                start = i;
            }
        } else {
            if (start != -1) {
                Token t;
                int count = i - start;
                t.size = count;
                t.data.token = (char*)malloc(count * sizeof(char));
                memcpy(t.data.token, line + start, count * sizeof(char));
                start = -1;
                add_element(p_tokens, &t, sizeof(Token), size, &capacity);
            }

            Token t;

            switch(ch) {
                case SUM:
                case SUB:
                case MUL:
                case DIV:
                case LBR:
                case RBR:
                    t.size = 0;
                    t.data.ch = ch;
                    add_element(p_tokens, &t, sizeof(Token), size, &capacity);
                    break;
                default:
                    return 1;
            }
        }
    }

    if (start != -1) {
        Token t;
        int count = len - start;
        t.size = count;
        t.data.token = (char*)malloc(count * sizeof(char));
        memcpy(t.data.token, line + start, count * sizeof(char));
        start = -1;
        // Will a copy of `t` in p_tokens be reseted on the next iteration?
        add_element(p_tokens, &t, sizeof(Token), size, &capacity);
    }

    free(line);
    line = NULL;

    return 0;
}

问题是在循环的下一次迭代中重新设置了数组中添加的元素。我不明白为什么?当我调用memcpy中的add_element时,它必须复制数组元素结构相关字段中Token结构的所有字段,不是吗?
我做错了什么?怎么解决?我不能已经。。。
修正二次误差
int add_element(void** arr, void* val, int t_size, int* size, int* capacity) {

    if ((*size) == (*capacity)) {
        *capacity += ARRAY_INC;
        *arr = realloc(*arr, (*capacity) * t_size);

        if (*arr == NULL) {
            return 1;
        }
    }

    memcpy(*arr + ((*size)++), val, t_size);

    return 0;
}

代码仍然有相同的问题。
补充
似乎我犯了错误,这里是*arr + ((*size)++)arrvoid**所以可能(*arr + some_num)会给出错误的偏移,但我不知道如何修复它。

最佳答案

scan_tokens中有初始分配:

*p_tokens = malloc(capacity * sizeof(Token));

[移除不必要的石膏]
在这里分配capacity * sizeof(Token)字节。
然后在add_element中,您有:
*arr = realloc(*arr, (*capacity) * sizeof(char));

在这里分配*capacity字节。
这当然是不正确的,而且很可能分配到很少。在add_element函数中,您应该分配t_size字节的倍数:
*arr = realloc(*arr, (*capacity) * t_size);

关于一个非常相关的注意事项:不要重新分配给传递给realloc函数的指针。如果realloc失败,它将返回一个空指针,导致您丢失原始指针。使用分配前检查的临时变量。

关于c - 如何将值正确复制到数组元素?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46517123/

10-11 23:17
查看更多