我在动态数组输入函数中使用realloc时出现分段错误(内核转储)

我在动态数组输入函数中使用realloc时出现分段错误(内核转储),c,memory-management,C,Memory Management,我为输入数组编写了一个组合输出代码。我为一个新数组编写了一个input\u数组函数。我为一个size\u t类型的单个数字编写了一个input\u decimal\u number函数。我将N设置为组合中的元素数。我通过了编译。下面是代码: #include <stdio.h> #include <stdlib.h> #include <limits.h> size_t input_decimal_number(void); size_t input_arr

我为输入数组编写了一个组合输出代码。我为一个新数组编写了一个
input\u数组
函数。我为一个
size\u t
类型的单个数字编写了一个
input\u decimal\u number
函数。我将N设置为组合中的元素数。我通过了编译。下面是代码:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

size_t input_decimal_number(void);
size_t input_array(int *array);
void combination(const int *array, int *combination_array,
                 size_t start, const size_t end, const size_t N, size_t i);

int main(void)
{
     size_t N, LEN;
     int *array;
     array = (int *)malloc(sizeof(int));
     LEN = input_array(array);

     printf("enter N value(0 < N <= %zd):\n", LEN); /* N is number of elements in a combination */
     while ((N = input_decimal_number()) > LEN)
          printf("N > %zd, enter N again: ", LEN);
     int combination_array[N];
     puts("Here are all combinations for this integer array:");
     combination(array, combination_array, 0, LEN - 1, N, 0);
     return 0;
}

size_t input_decimal_number(void)
{ /* here is a common size_t type single-number input functions */
     size_t decimal_number;
     _Bool input_check;
     while ((input_check = fscanf(stdin, "%zd", &decimal_number)) != 1)
          if (input_check != 1)
          {
               scanf("%*s");
               fprintf(stdout, "invalid input, enter this number again: ");
          }
     return decimal_number;
}

size_t input_array(int *array)
{ /* this is input array functions */
     size_t LEN = 0;
     char buf[BUFSIZ];
     void *alloc_check;
     fprintf(stdout, "Enter decimal integer arrays(use spaces key to separate every number):\n");
     while (fscanf(stdin, "%d", &array[LEN]) == 1)
     {
          alloc_check = realloc(array, (LEN + 1) * sizeof(int));
          if (alloc_check == NULL)
               ;
          else
               array = (int *)alloc_check;
          /* dynamically allocate memory for array */

          LEN++;
          if (getchar() == '\n')
               break;
     }
     if (LEN == 0)
     {
          printf("no number entered correctly.\n");
          exit(EXIT_FAILURE);
     } /*if no input, exit the whole program */
     setbuf(stdin, NULL);
     setvbuf(stdin, buf, _IOLBF, BUFSIZ);
     /* skip rest of input content */
     return LEN;
}

void combination(const int *array, int *combination_array,
                 size_t start, const size_t end, const size_t N, size_t i)
{
     /* this functions could find all combination of N elements in an array*/
     if (i == N)
     {
          for (int k = 0; k < N; k++)
               printf("%d ", combination_array[k]);
          putchar('\n');
          return;
     }
     for (start; start <= end && end - start + 1 >= N - i; start++)
     /* "end-start+1 >= N-i" makes sure that including i at N will make a combination with remaining elements at remaining positions */
     {
          combination_array[i] = array[start];
          combination(array, combination_array, start + 1, end, N, i + 1);
     }
}
#包括
#包括
#包括
尺寸输入十进制数字(无效);
大小输入数组(int*数组);
无效组合(常量int*数组,int*组合_数组,
大小\u t开始、常量大小\u t结束、常量大小\u t N、大小\u t i);
内部主(空)
{
尺寸,长度;
int*数组;
数组=(int*)malloc(sizeof(int));
LEN=输入_数组(数组);
printf(“输入N值(0=N-i”确保在N处包含i将与剩余位置处的剩余元素进行组合*/
{
组合_数组[i]=数组[start];
组合(数组、组合_数组、开始+1、结束、N、i+1);
}
}

当我输入像
123456
这样的内容,并再次输入N时,它变为ok!但如果我输入
1234567
,它变为
realloc():无效的下一个大小中止(堆芯转储)
,为什么?

您的堆已损坏,这会导致未定义的行为,请思考
的第二次迭代中会发生什么,而(fscanf(stdin,“%d”,&array[LEN])==1)
,当调用它以获取第二个输入时,分配的内存仍然只有一个
int
的空间,但您将该值分配给
数组[1]
这意味着数组应该至少有2个
int
s的空间,但第二个空间尚未分配

快速修复,使用
(LEN+2)

要将分配的空间传递给调用者函数,在这种情况下,
main
函数:

  • 或者将指针返回到分配的空间,然后通过其他方式(例如,通过指针参数)返回
    LEN

对于后者:

int *input_array(size_t *LEN) {//LEN will be passed as an argument pointer

    int *array;
    if ((array = malloc(sizeof *array)) == NULL) { //same as sizeof(int) but safer
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    fprintf(stdout, "Enter decimal integer arrays(space to separate every number):\n");
    while (fscanf(stdin, "%d", &array[*LEN]) == 1) {
        //no need for auxiliary pointer
        if ((array = realloc(array, (*LEN + 2) * sizeof *array)) == NULL) {
            perror("malloc");
            exit(EXIT_FAILURE);
        }
        (*LEN)++;
        if (getchar() == '\n')
            break;
    }
    if (LEN == 0) {
        fprintf(stderr, "no number entered correctly.\n");
        exit(EXIT_FAILURE);
    }
    return array; //return the allocated space
}
总的来说:

//...
size_t N, LEN = 0;
int *array;
array = input_array(&LEN); //allocated space assigned to array and LEN as an argument pointer
//...

组合函数中仍然存在潜在的问题,随着N的增长,组合的数量会减少到如果N==LEN,唯一打印的组合就是数组本身,如果这不是预期的输出,您也应该解决这个问题

size\u t
格式说明符是
%zu

使用
for
循环中的
size\u t i=0
来实现签名比较一致性。

您的
输入数组()
函数还有一个问题:您正在将
stdin
的缓冲区设置为本地数组,该数组在函数返回时不再存在:

size_t input_array(int *array)
{ /* this is input array functions */
     size_t LEN = 0;
     char buf[BUFSIZ];   <=====  This array ceases to exist when this function returns

     ...

     setbuf(stdin, NULL);
     setvbuf(stdin, buf, _IOLBF, BUFSIZ);  <==== stdin's buffer will disappear
     /* skip rest of input content */
     return LEN;
}
如果没有
static
,每次调用
input_array()
时,函数的每次调用都将有自己的
buf
数组。如果两个线程同时运行,程序中将有两个
buf
数组。但当函数返回时,这些数组将不再存在


添加了
static
关键字后,只有一个
buf
数组,只要程序在运行,它就会存在,所有调用
input\u array()的操作都会共享它

为什么
LEN+1
对于
realloc
来说还不够?@brushmank,在第二次scanf迭代中,分配的空间仍然只有一个int,堆被破坏,导致未定义的行为。我将此添加到我的答案中。如果我像
0 243-346那样输入数组,我在
输入十进制数
中发现另一个问题67-2764-4 0
,数组将出错。它可能会变成
0-34667-2764-4 0
。你能帮我一下吗?@brushmank,是的,要将分配的空间传递给main,你需要一个双指针,或者返回分配的空间,然后逐指针传递LEN,对于后者:。另一个问题是组合函数中,当N增大numb时组合的er将变小,如果N==LEN,它只打印
     static char buf[BUFSIZ];