1

我的代码在访问数组元素时导致分段错误,即使该元素已经被访问而没有问题。

int charToInt(char a)
{
    int b;
    if(isdigit(a))
    {   
        b = a - '0' - 1;
    }
    if(isalpha(a))
    {
        b = a - 65; 
    }
    return b;   
}

int validPosition(char **array, int r, int c, char* position, int slots)
{
    int i,k;
    if(strlen(position) == 5)
    {
        if(!isalpha(position[0]) || !isdigit(position[1]) || position[2]!=' ' || (position[3]!='N' && position[3]!='E' && position[3]!='W' && position[3]!='S')) //lathos gramma
        {
            printf("\n%s", "Invalid answear.This is an example of a valid answear: A5 N");
            return 2;
        }
        if( charToInt(position[0]) > r - 1 || charToInt(position[1]) > c - 1  )//ama vgainei eksw apo ta oria
        {
            printf("\n%s", "The position you choosed is out of the bountries...");
            return 2;
        }
        printf("\n%s%c%s","position[3] is: ",position[3], " but it doesn't work >_<"); // position[3] is N 
        if(position[3] == 'N') //the problem is here <~~~~~~~~~~~~~~~~~~~<
        {
            printf("\n%s", "come on");
            if(charToInt(position[0]) + slots < r)
            {
                for(i=charToInt(position[0])-1; i<charToInt(position[0])+slots; i++)
                {
                     if(array[i-1][charToInt(position[1])-1] != '.')
                     {
                         printf("\n%s", "The position you choosed is not valid because there is oneother ship there");
                         return 2;
                     }
                }
            }
            else
            {
                printf("\n%s", "The ship is going out of the bountries...");
                return 2;
            }
        }
    }
}

position持有字符串"A9 N"时,printf正确输出'N'position[3]。但是,由于某种原因,当它尝试执行if(position[3] == 'N')时,会发生分段错误。

示例程序运行:

定位示例:G3 E

航空母舰(5个地方),给出位置和方向:A9 N

1

位置[3] 是:N 但它不起作用>_<
4

3 回答 3

1

好吧,根据您的更新,您似乎遇到了各种各样的问题。为了将来参考,实际上添加(可能是简化的)代码显示您如何调用相关函数比尝试在评论中使用散文描述它更好。试图帮助你的人会减少猜测。

如果我正确阅读了您的评论,则调用的代码validPosition如下所示:

// "r and c are 9 and 9 in the specific example(rows columns)."
int rows = 9;
int columns = 9;

// "slots=5."
int slots = 5;

// "array is a 2d array and it contains characters(created with malloc)."
char **array = malloc(rows * columns * sizeof(char));

// "i created char position[10] in the function that called this function"
char position[10];
// "and with fgets(position, 10, stdin); i putted A9 N inside it."
fgets(position, 10, stdin);

validPosition(array, rows, columns, position, slots);

第一个问题是您对数组分配的描述(如果我误解了您的评论并且这实际上不是您在做什么,我深表歉意)。对于与两个下标操作一起使用的动态大小的二维数组,它看起来应该类似于下面的代码(array[index1][index2],因为它在 中validPosition)。当您以这种方式访问​​它们时,指针指向指针 ( char **array) 的行为与固定大小的多维数组 ( ) 不同。array[SIZE1][SIZE2]

// each entry in array should be a pointer to an array of char
char **array = malloc(rows * sizeof(char*));
for(i = 0; i < rows; i++)
    array[i] = malloc(columns * sizeof(char));

您还需要小心在fgets调用后使用位置。您应该检查返回值以确保它不是NULL(指示EOF或错误情况)。在这种情况下,字符串可能不会被\0终止。事实上,所有元素可能仍然未初始化(假设您在调用之前没有初始化它们)。这可能导致未定义的行为。

下一个问题是它validPosition不会在每个代码路径上都返回一个值。一个例子是如果strlen(position) != 5。另一种是如果您进入for循环并且array[i-1][charToInt(position[1])-1] != '.'永远不会为真(即,船舶放置被认为是有效的)。

一个说英语的人对一个希腊作者说这话很奇怪,让我们忽略国际化,只关注默认的 C 本地化。因此,对 position[0] 的检查就足够了,尽管您可能会考虑允许您的用户也使用小写字母。但是,当position[1]1-based转换为0-based 时,您没有考虑它是 的情况'0',这将导致charToInt返回-1。此外,您错误地在 . 的第二个数组下标中再次进行减法array[i-1][charToInt(position[1])-1]

同样,正如 Jite 和 BLUEPIXY 所指出的,您正在对 的结果进行两次额外的减法charToInt(position[0]):一个在 for 循环初始化程序 ( i=charToInt(position[0])-1) 中,一个在 的第一个数组下标中array[i-1][charToInt(position[1])-1]

一旦你解决了这个问题,你可能会发现你有时会错误地告诉用户他们的选择是无效的。这是因为您正在检查charToInt(position[0]) + slots < r而不是<= r.

正如我在评论中提到的,其中一种访问array很可能是您违反分段的罪魁祸首,而不是position[3] == 'N'. 您看不到输出的原因printf("\n%s", "come on");是您stdout似乎是行缓冲的,并且没有行尾来刷新它。它通常会在正常程序终止时自动刷新,但是您会出现段错误,因此不会发生这种情况。

最后,这些只是我注意到的语义错误。从风格上讲,代码也有待改进。例如,您似乎将要使用与您的子句类似的逻辑来实现else if(position[3] == 'E'else if(position[3] == 'W'和子句。这增加了您因错误地复制和粘贴而引入错误的可能性,并且当您需要在四个地方而不是一个地方进行更改时也会增加您的工作量。else if(position[3] == 'S'if(position[3] == 'N'

于 2013-04-03T04:14:27.617 回答
0

也许是分段错误array[i-1][charToInt(position[1])-1]

i: charToInt(position[0])-1: charToInt('A') - 1 : -1 <- 数组越界

于 2013-04-02T22:59:08.420 回答
0

由于术语“分段错误”我相信你在 Linux 机器上。使用gdb查找错误原因。以下是步骤。

  1. 使用附加的 -g 标志进行编译(例如 gcc -g my_prog.c)
  2. 运行调试器:gdb a.out
  3. 使用“列表”命令查找断点行(例如,函数的第一行)
  4. 在该行上设置断点: b 25 (如果 25 是该行)
  5. 使用“运行”命令运行程序
  6. 使用命令 'next' 执行下一行代码

现在执行将在该行暂停,您可以检查内存、打印变量内容和其他内容。但通常您想确定执行失败的行以及哪个变量中的内容。

稍微玩一下内存,您就会很容易找到问题所在。就个人而言,我的代码不适用于 gdb 支持。

于 2013-04-02T20:53:00.813 回答