C realloc:下一个大小无效,aSan 说 heap-use-after-free
C realloc: invalid next size, aSan says heap-use-after-free
如果这是一个重复的问题,我很抱歉,但我查看了其他各种答案,但它们似乎不适用于我的代码。
我定义了一个结构 Coord,它只是一个 x 和 y,每个限制为 4 位。
typedef struct {
unsigned int x:4;
unsigned int y:4;
} Coord;
我通过执行 Coord* snakeArr = malloc(2 * sizeof(Coord));
并使用 int snakeArrSize = 2;
跟踪数组的大小来使用坐标数组。我做了这个函数来模仿 unshift()
javaScript 函数。
void unshiftCoord(Coord *arr, Coord value, int *arrSize) {
// Debugging
printf("%li\n", (*arrSize + 1) * sizeof(Coord));
fflush(stdout);
// Allocate an extra slot in the array
arr = realloc(arr, (*arrSize + 1) * sizeof(Coord));
// Shift everything over
for (int i = *arrSize; i > 0; i--) {
arr[i] = arr[i - 1];
}
// Set the first value in the array
arr[0] = value;
// Update arrSize variable
*arrSize += 1;
}
这工作得很好,但由于某种原因,当我第 5 次调用该函数时,它给出了“下一个尺寸无效”错误。这是我的程序的输出:
12
16
20
24
28
realloc(): invalid next size
Aborted (core dumped)
如您所见,当新大小增加到 28 时,realloc() 失败。
我遇到的一种解决方案是使用 aSan。我在我的编译器标志中使用 -fsanitize=address
完成了此操作,当我 运行: ERROR: AddressSanitizer: heap-use-after-free
... 和一条非常长的消息时,我做对了。需要的话我放在this google doc.
成功后
arr = realloc(arr, (*arrSize + 1) * sizeof(Coord));
*arrSize += 1;
arr
有 *arrSize
元素,所以 arr[*arrSize]
是 out-of-range,你不能用它来存储东西。
循环
for (int i = *arrSize; i > 0; i--) {
应该是
for (int i = *arrSize - 1; i > 0; i--) {
还应检查 realloc()
的结果以避免取消引用 NULL
。
还有一个关键点:参数arr
是已传递内容的副本,因此对其进行修改不会影响已传递内容。因此,如果 realloc()
returns new buffer,它会丢失,原始无效的 arr
将在后面的过程中使用。
为避免这种情况,应传递指向变量的指针而不是 arr
,并且应通过指针修改变量。
如果这是一个重复的问题,我很抱歉,但我查看了其他各种答案,但它们似乎不适用于我的代码。
我定义了一个结构 Coord,它只是一个 x 和 y,每个限制为 4 位。
typedef struct {
unsigned int x:4;
unsigned int y:4;
} Coord;
我通过执行 Coord* snakeArr = malloc(2 * sizeof(Coord));
并使用 int snakeArrSize = 2;
跟踪数组的大小来使用坐标数组。我做了这个函数来模仿 unshift()
javaScript 函数。
void unshiftCoord(Coord *arr, Coord value, int *arrSize) {
// Debugging
printf("%li\n", (*arrSize + 1) * sizeof(Coord));
fflush(stdout);
// Allocate an extra slot in the array
arr = realloc(arr, (*arrSize + 1) * sizeof(Coord));
// Shift everything over
for (int i = *arrSize; i > 0; i--) {
arr[i] = arr[i - 1];
}
// Set the first value in the array
arr[0] = value;
// Update arrSize variable
*arrSize += 1;
}
这工作得很好,但由于某种原因,当我第 5 次调用该函数时,它给出了“下一个尺寸无效”错误。这是我的程序的输出:
12
16
20
24
28
realloc(): invalid next size
Aborted (core dumped)
如您所见,当新大小增加到 28 时,realloc() 失败。
我遇到的一种解决方案是使用 aSan。我在我的编译器标志中使用 -fsanitize=address
完成了此操作,当我 运行: ERROR: AddressSanitizer: heap-use-after-free
... 和一条非常长的消息时,我做对了。需要的话我放在this google doc.
成功后
arr = realloc(arr, (*arrSize + 1) * sizeof(Coord));
*arrSize += 1;
arr
有 *arrSize
元素,所以 arr[*arrSize]
是 out-of-range,你不能用它来存储东西。
循环
for (int i = *arrSize; i > 0; i--) {
应该是
for (int i = *arrSize - 1; i > 0; i--) {
还应检查 realloc()
的结果以避免取消引用 NULL
。
还有一个关键点:参数arr
是已传递内容的副本,因此对其进行修改不会影响已传递内容。因此,如果 realloc()
returns new buffer,它会丢失,原始无效的 arr
将在后面的过程中使用。
为避免这种情况,应传递指向变量的指针而不是 arr
,并且应通过指针修改变量。