调整动态数组大小后出现分段错误
Segmentation fault after resizing dynamic array
我遇到了以下代码的分段错误,我真的不知道问题出在哪里。该程序应该包含一个动态的无符号整数数组,该数组在函数 setBreakPoint 中调整大小。分段错误发生在数组的第二个元素的分配过程中(第一个没有问题)。
#include <stdio.h>
#include <stdlib.h>
void setBreakPoint(unsigned int **break_points, unsigned int *number_of_break_points, unsigned int new_break_point)
{
unsigned int *buffer;
if(new_break_point > 0)
{
buffer = realloc(*break_points, ++(*number_of_break_points) * sizeof(unsigned int) );
if(buffer != NULL)
{
*break_points = buffer;
*break_points[(*number_of_break_points) - 1] = new_break_point;
}
}
return;
}
int main(void)
{
unsigned int *break_points = NULL;
unsigned int number_of_break_points = 0;
setBreakPoint(&break_points, &number_of_break_points, 10);
setBreakPoint(&break_points, &number_of_break_points, 5);
free(break_points);
return 0;
}
这里是 valgrind 的输出。总共分配了 12 个字节,这看起来相当合法(第一次函数调用时为 4 字节,第二次为 8 字节)。据我所知,似乎对 NULL 指针进行了赋值,但我不明白为什么。
==8695== Invalid write of size 4
==8695== at 0x4005BA: setBreakPoint (in /break_points)
==8695== by 0x400605: main (in /break_points)
==8695== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==8695==
==8695== HEAP SUMMARY:
==8695== in use at exit: 8 bytes in 1 blocks
==8695== total heap usage: 2 allocs, 1 frees, 12 bytes allocated
==8695==
==8695== LEAK SUMMARY:
==8695== definitely lost: 0 bytes in 0 blocks
==8695== indirectly lost: 0 bytes in 0 blocks
==8695== possibly lost: 0 bytes in 0 blocks
==8695== still reachable: 8 bytes in 1 blocks
==8695== suppressed: 0 bytes in 0 blocks
问题出在这个表达式中:
*break_points[(*number_of_break_points) - 1]
索引运算符 []
的优先级高于指针引用运算符 *
,因此您的代码解析错误。应该是:
(*break_points)[(*number_of_break_points) - 1]
奇怪的是,您在 (*number_of_break_points)
中添加了不需要的括号。
有趣的是,由于您使用的是指向指针的指针,因此 *(p[i])
和 ``(*p)[i]are valid. Also, when the index value is
0` 的结果值都是同样,这就是为什么第一次成功第二次失败的原因。
PS:请注意,您还有另一个小错误:如果 realloc
失败,您无论如何都会增加计数器。这样会更简单:
buffer = realloc(*break_points, (*number_of_break_points) * sizeof(unsigned int) );
if(buffer != NULL)
{
*break_points = buffer;
buffer[(*number_of_break_points)++] = new_break_point;
}
代码 *break_points[(*number_of_break_points) - 1]
与您预期的不同。使用我们在 C 中的运算符优先级,它的计算结果为 * (break_points[..])
。你应该写 `(*break_points)[..].
我遇到了以下代码的分段错误,我真的不知道问题出在哪里。该程序应该包含一个动态的无符号整数数组,该数组在函数 setBreakPoint 中调整大小。分段错误发生在数组的第二个元素的分配过程中(第一个没有问题)。
#include <stdio.h>
#include <stdlib.h>
void setBreakPoint(unsigned int **break_points, unsigned int *number_of_break_points, unsigned int new_break_point)
{
unsigned int *buffer;
if(new_break_point > 0)
{
buffer = realloc(*break_points, ++(*number_of_break_points) * sizeof(unsigned int) );
if(buffer != NULL)
{
*break_points = buffer;
*break_points[(*number_of_break_points) - 1] = new_break_point;
}
}
return;
}
int main(void)
{
unsigned int *break_points = NULL;
unsigned int number_of_break_points = 0;
setBreakPoint(&break_points, &number_of_break_points, 10);
setBreakPoint(&break_points, &number_of_break_points, 5);
free(break_points);
return 0;
}
这里是 valgrind 的输出。总共分配了 12 个字节,这看起来相当合法(第一次函数调用时为 4 字节,第二次为 8 字节)。据我所知,似乎对 NULL 指针进行了赋值,但我不明白为什么。
==8695== Invalid write of size 4
==8695== at 0x4005BA: setBreakPoint (in /break_points)
==8695== by 0x400605: main (in /break_points)
==8695== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==8695==
==8695== HEAP SUMMARY:
==8695== in use at exit: 8 bytes in 1 blocks
==8695== total heap usage: 2 allocs, 1 frees, 12 bytes allocated
==8695==
==8695== LEAK SUMMARY:
==8695== definitely lost: 0 bytes in 0 blocks
==8695== indirectly lost: 0 bytes in 0 blocks
==8695== possibly lost: 0 bytes in 0 blocks
==8695== still reachable: 8 bytes in 1 blocks
==8695== suppressed: 0 bytes in 0 blocks
问题出在这个表达式中:
*break_points[(*number_of_break_points) - 1]
索引运算符 []
的优先级高于指针引用运算符 *
,因此您的代码解析错误。应该是:
(*break_points)[(*number_of_break_points) - 1]
奇怪的是,您在 (*number_of_break_points)
中添加了不需要的括号。
有趣的是,由于您使用的是指向指针的指针,因此 *(p[i])
和 ``(*p)[i]are valid. Also, when the index value is
0` 的结果值都是同样,这就是为什么第一次成功第二次失败的原因。
PS:请注意,您还有另一个小错误:如果 realloc
失败,您无论如何都会增加计数器。这样会更简单:
buffer = realloc(*break_points, (*number_of_break_points) * sizeof(unsigned int) );
if(buffer != NULL)
{
*break_points = buffer;
buffer[(*number_of_break_points)++] = new_break_point;
}
代码 *break_points[(*number_of_break_points) - 1]
与您预期的不同。使用我们在 C 中的运算符优先级,它的计算结果为 * (break_points[..])
。你应该写 `(*break_points)[..].