c - 调整动态数组大小后出现段错误

标签 c segmentation-fault dynamic-arrays

我遇到了以下代码的段错误,我真的不知道问题出在哪里。该程序应该包含一个动态的无符号整数数组,该数组在函数 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] 都是有效的.此外,当索引值为 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;
    }

关于c - 调整动态数组大小后出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34382449/

相关文章:

c - 如何在 C 中的同一个 ADT 中使用多种数据类型?

c++ - 递增指向 0 大小的动态数组的指针是否未定义?

c++ - 递归 count_files 函数不返回完整结果

c - 为什么 select() 不考虑超时,尤其是在多线程中

c - 访问链接列表或在 Linux 上执行 malloc() 时出现段错误

c++ - 为什么我总是在 C++ 套接字的服务器端接收数据?

c++ - C++中的访问冲突写入位置

c++ - 指向数组参数的双指针错误

c - 查找当前元素右侧的所有元素的计数,其值小于C中数组中的当前元素

python - DataFrame.to_json() 的段错误