【问题标题】:Segmentation Fault while initializing array in C在 C 中初始化数组时出现分段错误
【发布时间】:2014-12-29 05:00:34
【问题描述】:

我是 C 的初学者。我浏览了现有的问题,但无法理解,因为它们涉及字符串和字符。这是我的代码的一小部分:

#define grid 32

int main (void)
{
int NU, NV, NP;
NU=(grid-1)*grid;
NV=grid*(grid-1);
NP=grid*grid;
double u[NU], uc[NU];
double v[NV], vc[NV];
double p[NP], pc[NP];

//Initialization


// Initializing u

    for (i=0; i<(grid-1); i++)
    {
        for (j=0; j<(grid); j++)
        {
            int k=j*grid+i;

            if (j==(grid-1))
            {
            u[k]=1.0;
            }
            else if (j==(grid-2) && i>0 && i<(grid-2))
            {
            u[k]=1.0;
            }
            else
            {
            u[k]=0.0;
            }
        }
    }


// Initializing v
for (j=0; j<(grid-1); j++)
{
    for (i=0; i<grid; i++)
    {
        int k=j*grid+i;
        v[k]=0.0;
    }
}

// Initializing p
for (j=0; j<grid; j++)
{
    for (i=0; i<grid; i++)
    {
        int k=j*grid+i;
        p[k]=1.0;
    }
}

我正在尝试初始化这些数组,但出现分段错误。 请帮我解决这个问题。

【问题讨论】:

  • 我需要查看数组初始化代码。
  • 为什么不:int NU = (grid-1) * grid; 和 int NV = grid * (grid-1); 和 int NP = grid * grid;,每个变量在创建时初始化?
  • @JonathanLeffler 试过了,还是一样的问题。
  • 哦 - 对不起;这是风格问题,而不是崩溃的根源。您是否处于任何类型的受限环境中(嵌入式系统,...)?您已经创建了 48 KiB 的阵列,这不应该对当今的大多数系统造成压力。你怎么知道是这些初始化崩溃了?您是否在循环集之间放置了printf() 语句,以便知道哪个循环崩溃了? (确保格式字符串每次都以换行符结尾。)

标签: c arrays segmentation-fault


【解决方案1】:

这行是问题所在:

int k=j*grid+i;

它使您的数组索引超出范围。当您访问u[k] 时,您会遇到段错误。此外,无需使用 2 个循环来初始化一维数组,除非您尝试在此处实现我不知道的特定逻辑。

【讨论】:

  • 更具体地说,它应该是 int k = j*(grid-1) + i; 。其他几个地方也有同样的问题。
【解决方案2】:

你定义了

NU=(grid-1)*grid;
NV=grid*(grid-1);
NP=grid*grid;

现在让我们看看您在循环中访问数组元素的程度。

for (i=0; i<(grid-1); i++)
{
    for (j=0; j<(grid); j++)
    {
        int k=j*grid+i; // so in the max case k = (grid-1)*grid+grid-2 = grid*grid+2
        ...             // and it is larger than NU so it will be accessing wrong memory
                        // memory region
    }
}

按照相同的分析,确保其他数组初始化不超过边界。

【讨论】:

    【解决方案3】:

    数组初始化导致 SEGFALT 的唯一原因是读取或写入不存在的元素。

    实现这一点的最常见方法是使用超出数组边界的索引。在 C 中,最低元素是索引0(零),最高元素是N-1,其中N 是为数组声明的元素数。

    int  array [5000];
    
    array [-1] = 0;   /* BAD */
    array [5000] = 0;   /* BAD */
    

    这两个都是无效访问。他们可能会出现 SEGFAULT。他们可能会改变另一个变量的值。他们似乎什么都不做。或者它们可能看起来有效。

    【讨论】:

    • 据我所见,我已经明确定义了数组并仅初始化定义的数组。应该没有歧义。
    • @TanmayAgrawal:代码还很不清楚。声明最清楚,但初始化逻辑很难理解。
    • 让我说得更清楚些。我希望 P 是一个所有值都等于 1 的 grid*grid 数组。数组 V 将是一个 grid*(grid-1) 维度,所有值都为 0。数组 u 将是 (grid-1)*grid 维度,所有(j==(grid-1)) 即最高 y 方向等于 1,(j==(grid-2) && i>0 && i
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    • 2020-07-30
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2011-12-20
    • 2016-06-03
    相关资源
    最近更新 更多