我需要一个将值放入数组的通用函数,我写道:
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();
}
可能会给出错误的偏移,但我不知道如何修复它。
答案 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
指针。