0

这个 c 程序在 Windows 中运行良好,但在 Linux 中显示段错误。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>

void comb(long int *arr,long int n,long int r,long int stick)
{
    long int check=1,sum =0;
    int poscheck = 0,status = 0;
    long int *temp = malloc(r * sizeof(long int));
    long int *pos = malloc(r * sizeof(long int));
    long int *rept = malloc(r * sizeof(long int));
    memset(pos, 0, r*sizeof(long int));
    memset(rept, 0, r*sizeof(long int));

    while (check <= pow(n,r))
    {
        for (long int i = 0; i < r; i++) //for making the number of array
        {
            for(long int j = 0; j < r; j++) //For checking that no number is repeating.
            {
                if(i == j) continue; //for skip checking of the same element
                else if(pos[i] == pos[j])
                {
                    poscheck = 1;
                    break;
                }
            }
            if(poscheck == 1) break;
            temp[i] = arr[pos[i]];
            sum += temp[i];
        }
        if((sum == stick) && poscheck == 0)
        {
            for(long int i = 0 ; i< r ; i++)
            {
                printf("%ld ",temp[i]);
            }
            status = 1;
            printf("\n");
            break;
        }
        sum = 0,poscheck = 0;
        for (long int i = 0; i < r; i++)
        {
            if (pos[i] == n - 1)
            {
                rept[i]++; //To check how much time the number is repeated in a column
            }
            if ((pos[i] == n - 1) && (rept[i] == pow(n, r-i-1))) //If it is repeated a specific number of time then change the value of it's previous position
            {
                if (pos[i - 1] == n - 1) //if the previous number is the last number then it will start the series again 
                {
                    pos[i - 1] = 0;
                }
                else
                    pos[i - 1]++; //If the previous number is not the last number of series then go to the next number
                rept[i] = 0;
            }
        }
        if (pos[r - 1] < n - 1) //for go to the next number of series in the last line
        {
            pos[r - 1]++;
        }
        else
        {
            pos[r - 1] = 0; //if it is the last number of series then start form the first again
        }
        check++;
    }
    if(status == 0)
    {
        printf("-1\n");
    }
    free(pos); //Does not know why this is showing "double free or corruption (out)" in linux but working in windows.
    free(rept);
    free(temp);
} 
int main()
{
    long int n,data[3],j=0;
    scanf("%ld",&n);
    long int *arr = malloc(n*sizeof(long int));
    while(j < n)
    {
        for(long int i = 0; i< 3; i++)
        {
            scanf("%ld",&data[i]);
        }
        for(long int i = 0; i < data[1]; i++)
        {
            arr[i] = i+1;
        }
        comb(arr,data[1],data[2],data[0]);
        j++;
    }
    free (arr);
    return 0;
}

给定的输入是

12 8 3
10 3 3
9 10 2
9 10 2

这在linux中显示

1 3 8 
-1
munmap_chunk(): invalid pointer
Aborted (core dumped)

这在 Windows 中完美显示

2 3 7
-1
5 4
1 8

我在 Windows 和 Linux 中都使用了 gcc 和 tcc 编译器,但在 Linux 中都给出了相同的错误。

无法理解为什么问题在 Linux 中出现。

4

2 回答 2

0

如果输入是

1 3 8 
-1

主要是

n = 1

arr = memory for 1 long int

在 for(long int i = 0; i< 3; i++)

data array = 3 8 -1

在: for(long int i = 0; i < 数据[1]; i++)

arr[i] = some value    

但是 arr 数组将迭代 8 次并尝试分配 arr[i],即使 arr 有一个元素。

于 2018-11-02T16:30:27.733 回答
0

对于以下开头的行:

if (pos[i - 1] == n - 1) 

'i' 有时会为 0(在 10 3 3 的输入上),因此此时您正在将 pos[-1] 设置为值 - 即:设置内存您不应该将其设置为干扰稍后释放,因为 malloc 使用指针之前的值来获取免费信息。

为了验证,如果我在 if 比较之前添加了一个 print 并运行您的示例:

if(i==0) printf("bad I pos\n");

在出现错误之前,它会在多个位置打印出来。

于 2018-11-12T17:01:30.013 回答