【问题标题】:Segmentation Fault in C using calloc使用 calloc 的 C 中的分段错误
【发布时间】:2013-12-17 21:03:40
【问题描述】:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int queensonboard(int n,int m)
{
    int count=0,i,j,flag,x[100];
    char **board;
  /*   board= (char**)calloc(sizeof(char*),n);
    for(i=0;i<n;i++)
    {
        board[i]= (char*)calloc(sizeof(char),m);
    }
   for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            scanf("%c",&board[i][j]);
        }
    }*/
   // x==(int*)calloc(sizeof(int),n);
    flag=0;
    for(i=0;i<n;i++)
    {
        x[i]=0;
    }
    while(i>0)
    {
        while(x[i]<m)
        {
            x[i]++;
           // if(board[i][x[i]]!='#')
         //   {
                for(j=0;j<i;j++)
                {
                    if(x[j]==x[i])
                    {
                        flag=1;
                    }
                    else if(x[j]-x[i]==abs(j-i))
                    {
                        flag=1;
                    }
                    else
                    {
                        flag=0;
                    }
                }
                if(flag==0 && i==n-1)
                {
                    count++;
                }
                else if(flag==0)
                {
                    i++;
                }             
           //}
        }
        x[i]=-1;
        i--;
    }
    printf("%d\n",count);

}

int main() {

    int i,n,m,j;
    scanf("%d",&i);
    for(j=1;j<=i;j++)
    {
        scanf("%d %d",&n,&m);
        queensonboard(n,m);
    }
    return 0;
}

这是代码。该程序在动态分配任何数组 x 或 board 时给出分段错误。(在此处注释。)

那是我尝试使用 calloc 进行分配的时候。 无法真正弄清楚为什么会这样。尝试改变薄,但仍然发生。

【问题讨论】:

  • 你为什么要转换calloc的返回值?你为什么注释掉相关的代码。 x==(int*)calloc(sizeof(int),n)x=(int*)calloc(sizeof(int),n)。为什么将x 声明为int[100]
  • 如果calloc 正在返回NULL,您应该找出原因:if (board == NULL) { perror("could not allocate board"); }
  • 你确定 n 和 m 不为零吗?
  • 请显示您正在执行的有问题的确切代码,而不是您为不出现问题而修改的代码,并显示确切输入 您正在向程序提供。
  • @DavidHefferman:我假设x 的声明为int [100] 是在int *x;x==calloc(…); 之后实施的解决方法,但没有工作。因此,问题中的代码以掩盖原始问题的方式进行了修改。

标签: c segmentation-fault


【解决方案1】:

calloc的定义如下:

void *calloc(size_t num, size_t size);

num 要分配的元素数量。
size每个元素的大小。

你的论点交换了。应该是这样的:

board = calloc(n, sizeof(char *));
for(i = 0; i < n; i++)
{
    board[i]= calloc(m, sizeof(char));
}

另外,这行不正确:

x == (int*)calloc(sizeof(int), n);

这是将x 的地址与calloc 返回的地址进行比较。逻辑也不对。您定义x 的方式是一个包含100 个ints 的数组。

如果你想要一个int 指针数组,你需要这样做:

int *x[100];

如果你想要一个指向 100 个ints 数组的指针,你需要这样做:

int (*x)[100];

如果您只是尝试为x 分配内存,那么您已经通过声明完成了该操作:

int x[100]; 

【讨论】:

  • 乘法是可交换的
  • @DavidHeffernan:对齐不是。这可能不是导致 OP 问题的原因,但 calloc 应该以正确的顺序与参数一起使用。
  • @EricPostpischil 对齐很重要,但我的理解是 calloc(和 malloc)返回的指针对齐适合所有对象。
  • @DavidHeffernan:C 2011 更改了分配例程的规范,说它们返回一个针对基本对齐对象适当对齐的指针。如果实现支持扩展对齐,那么以不正确的顺序传递calloc 参数可能会导致它不知道您分配的对象具有扩展对齐。例如,一个实现可以支持 16 字节的 SIMD 向量类型或 4096 字节的内存页面分配,而 calloc(16, 3)calloc(4096, 3) 不会为这些提供所需的对齐方式。
  • @DavidHeffernan:显然,这不是这里的问题,但是否真的有必要为使用例程以记录的方式而不是使用完全不必要的更改提供防御?
【解决方案2】:

分段错误的明显解释是您正在取消引用无效指针。发生这种情况的明显方法是对calloc 的任何调用都返回NULLcalloc 在失败时会这样做。您没有检查 calloc 的返回值是否有错误,我认为其中一个调用很可能返回 NULL,因为您提供了无效参数。

因此,通过检查对calloc 的调用的返回值并检查您传递的输入参数来调试问题。我知道必须这样做很令人沮丧,但是您必须检查所有用户输入中的错误,并且必须检查所有调用内存分配函数的返回值。


这一行

x==(int*)calloc(sizeof(int),n)

您在哪里执行比较而不是分配也显然是有问题的。你的意思是:

int *x = calloc(n, sizeof(int));

是的,正如其他人指出的那样,您已经交换了 calloc 的参数。你当然应该解决这个问题,但我不认为这是你的问题的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 2016-03-22
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多