调整动态数组大小后的分段错误

时间:2015-12-20 15:16:57

标签: c segmentation-fault dynamic-arrays

我收到了以下代码的Segmentation故障,我真的无法找出问题所在。该程序应该包含一个无符号整数的动态数组,它在函数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

2 个答案:

答案 0 :(得分:2)

问题在于这个表达式:

*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;
    }

答案 1 :(得分:1)

代码*break_points[(*number_of_break_points) - 1]无法正常运行。使用C中的运算符优先级,它的计算结果为* (break_points[..])。你应该写`(* break_points)[..]。