c - 使用 realloc 收缩后的内存泄漏
问题描述
我不知道格式化发生了什么,但我无法使用 Ctrl+K 将选定的块标记为代码。对不起
我使用带有标志的 gcc 作为编译器并运行 valgrind:
valgrind --leak-check=full -q --error-exitcode=1
我正在尝试编写一个用于加法和减法的计算器。这些数字存储在一个固定大小的数组中,用 10000 数字系统编写:数组的每个元素都有一个分配的内存用于四位数字:
#include <stdlib.h>
#include <limits.h>
#define ELEMENTS 8
#define NUM_INT 4 //Number of digits
typedef struct numb {
int* digits;
int how_many; //How many cells with 4 digits
} numb;
void create(numb** tab) {
*tab = realloc(*tab, ELEMENTS * sizeof(**tab));
for (int i = 0; i < ELEMENTS; i++) {
numb cell;
cell.digits = calloc(NUM_INT, sizeof (*cell.digits));
cell.how_many = 1;
(*tab)[i] = cell; // Put in original array.
}
(*tab)[ELEMENTS-2].digits[0] = -1; // Don't bother about the values
(*tab)[ELEMENTS-1].digits[0] = 1;
}
valgrind 在两个函数中显示了一个问题:
添加两个结构
//help function int simple_add(int w, int m, int* p) { int number; int result = w + m + *p; if (result >= 10000) { *p = division(result); //division by multiplication while p*i<=10000 number = result - 10000*(*p); } else { number = result; *p = 0; } return number; } //problematic void add(numb* a, numb* b) { numb *big; numb *small; if (a->how_many != b->how_many) { small = min(a, b); //simple min and max functions, not written for clarity big = max(a, b); } else { big = a; small = b; } int left = 0; int i = 0; while (i < small->how_many) { big->digits[i] = simple_add(big->digits[i], small->digits[i], &left); i++; } while (left != 0) { if (i == big->how_many) { if ((size_t)i*NUM_INT*sizeof(int) >= sizeof(big->digits)) { int size; if ((size_t)i*NUM_INT*sizeof(int) + 2 >= INT_MAX) size = INT_MAX-1; else size = (size_t)i*NUM_INT*sizeof(int) + 2; big->digits = realloc(big->digits, size); } big->digits[i++] = left; big->how_many++; pom = 0; } else { big->digits[i] = simple_add(big->digits[i], 0, &left); i++; } } *a = *big; }
将值设置为 0
void clear(numb* a) { a->digits = realloc(a->digits, NUM_INT*sizeof(int)); a->digits[0] = 0; a->how_many = 1; }
对于小数字,它适用于 valgrind,没有错误。但是,随着测试文件中的值变大,我得到了 stackovflow/segmentation 错误:
我提出了三种来自 valgrind 的错误以减少混乱:
就在分段错误之前:
Invalid free() / delete / delete[] / realloc()
==13932== at 0x4837D7B: realloc (vg_replace_malloc.c:826)
==13932== by 0x10A084: clear (address)
==13932== by 0x10A298: interpreter (in address)
==13932== by 0x10A375: game (in address)
==13932== by 0x10A436: main (in address)
Address 0x4a3ebc0 is 0 bytes inside a block of size 34 free'd
==13932== at 0x4837D7B: realloc (vg_replace_malloc.c:826)
==13932== by 0x10A084: clear (in /address)
==13932== by 0x10A298: interpreter (in address)
==13932== by 0x10A375: game (in /address)
==13932== by 0x10A436: main (in /address)
==13932== Block was alloc'd at ==13932== at 0x4837D7B: realloc (vg_replace_malloc.c:826) ==13932== by 0x10943A: add (in /address)
==13932== by 0x10A1F8: interpreter (in address)
==13932== by 0x10A375: game (in address)
Invalid write of size 4
==13932== at 0x10A096: clear (in /address)
==13932== by 0x10A298: interpreter (in /address)
==13932== by 0x10A375: game (in /address)
==13932== by 0x10A436: main (in /address)
==13932== Address 0x0 is not stack'd, malloc'd or (recently) free'd
大多数情况下,这是无效的写入或读取;无效的免费只出现一次。我不想把所有消息的块弄得乱七八糟,但如果你需要,我可以粘贴它。
创建的数组在程序结束后被释放。
请,我会很感激你的建议。对于小数字它有效,因此如果我们去大数字,我很难跟踪正在发生的事情。这些数字应该是 <INT_MAX
编辑 我已经运行了一些测试,并在添加和清除中发现了错误,但我不知道如何修复它。
问题:我必须变量并添加 using add() 第一个为零,因此它只有一个单元格 [0] ::= num 第二个超过 10000(例如:16547),因此它有两个细胞 [6547][1] ::= num b
**我发现问题的地方”
将 b 添加到 a; 一个= 0; b = 16547
clear a //假设为0
打印出 b <- 我有一个错误
==52293== 大小为 4 的读取无效
==52293== 在 0x10CC75:print_a_number (call5.c:355)
==52293== 通过 0x10D027:解释器 (call5.c:397)
==52293== 通过 0x10D35F: rozgrywka (call5.c:453)
==52293== by 0x10D521: main (call5.c:496)
==52293== 地址 0x58c6804 是大小为 34 的块内的 4 个字节
free'd ==52293== 在 0x4837D7B : realloc (vg_replace_malloc.c:826)
==52293== by 0x10CD65: clear (call5.c:367)
==52293== by 0x10D215: 解释器 (call5.c:426)
==52293== by 0x10D35F: rozgrywka (call5.c:453)
==52293== by 0x10D521: main (call5.c:496)
==52293== 块被分配在
==52293== 在 0x4837D7B: realloc (vg_replace_malloc.c:826)
==52293== by 0x10B887: 添加 (call5.c:117)
==52293== by 0x10D115: 解释器 (call5.c:406)
==52293== by 0x10D35F: 游戏 (call5.c:453)
== 52293== 由 0x10D521: 主要 (call5.c:496)
我们记得, clear 重新分配了大小并离开了第一个单元格。但是,其他单元格被释放。似乎第二个单元格丢失了 [1],但我不明白,如果我已将值分配给*a
add 中的指针。
解决方案
推荐阅读
- spring - 将弹簧迁移到弹簧引导控制器不起作用
- javascript - 为什么所有 redux reducer 函数都在运行时执行?
- python - Keras 中的回调异常 - Tensorflow 2.0 - Python
- c# - 使用 linq 获取具有特定对象属性的列表的一部分
- java - 如何将数据保存到房间?
- firebase - 使用 firestore 文档快照侦听器进行本地打印
- swift - Swift IOS Chart - 堆积条形图
- php - nginx 没有打开 index.php
- ios - 目标 c - 尝试在队列中复制 NSArray 时获取 exc_bad_access
- javascript - 如何在我的数组中使用 javascript 中的 foreach?