如何正确地将值复制到数组元素?

时间:2017-10-01 21:35:07

标签: c

我需要一个将值放入数组的通用函数,我写道:

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结构的所有字段,它不是吗?
我做错了什么以及如何解决?我不能得到......

FIXED SECONDARY ERROR

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;
}

代码仍有同样的问题 的 ADDED
似乎我收到了错误,它在*arr + ((*size)++) arr void** (*arr + some_num),所以private BigInteger calculateProduct(char[] letters) { int OFFSET = 65; BigInteger[] bigPrimes = Arrays.stream( new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113 }) .mapToObj(BigInteger::valueOf) .toArray(BigInteger[]::new); BigInteger result = BigInteger.ONE; for (char c : letters) { //System.out.println(c+"="+(int)c); if (c < OFFSET) { return new BigInteger("-1"); } int pos = c - OFFSET; result = result.multiply(bigPrimes[pos]); } return result; } @Test public void test() { assertThat(calculateProduct(capitalize("carthorse"))).isEqualTo(calculateProduct(capitalize("orchestra"))); } private char[] capitalize(String word) { return word.toUpperCase().toCharArray(); } 可能会给出错误的偏移,但我不知道如何修复它。

2 个答案:

答案 0 :(得分:4)

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失败,它将返回一个空指针,导致您丢失原始指针。在分配之前使用您检查的临时变量。

答案 1 :(得分:0)

谢谢大家的帮助,我收到了错误消息。在我的函数的正确变体下面:

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((char*)(*arr) + (*size) * t_size, (char*)val, t_size);
    ++(*size);

    return 0;
}

我需要将void指针强制转换为char指针。