我在动态数组输入函数中使用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];