问题描述
如果这是一个重复的问题,我感到非常抱歉,但是我查看了其他各种答案,它们似乎不适用于我的代码。
我定义了一个结构坐标,它只是x和y分别限制为4位。
typedef struct {
unsigned int x:4;
unsigned int y:4;
} Coord;
我通过执行Coord* snakeArr = malloc(2 * sizeof(Coord));
并使用int snakeArrSize = 2;
跟踪数组的大小来使用Coords数组。我已经将此函数模仿了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;
}
这工作得很好,但是由于某些原因,当我第五次调用该函数时,它会给出“无效的下一个尺寸”错误。这是我的程序的输出:
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]
超出范围,您不能使用它来存储内容。
循环
for (int i = *arrSize; i > 0; i--) {
应该是
for (int i = *arrSize - 1; i > 0; i--) {
还应检查realloc()
的结果,以免取消引用NULL
。
还有一个关键点:参数arr
是所传递内容的副本 ,因此对该参数的修改不会影响所传递的内容。因此,如果realloc()
返回新缓冲区,它将丢失并且原始无效的arr
将在以后的过程中使用。
为避免这种情况,应传递指向变量的指针而不是arr
,并应通过指针进行变量的修改。