【问题标题】:Segmentation Fault with structs and functions结构和函数的分段错误
【发布时间】:2014-05-09 02:14:07
【问题描述】:


我在查找和解决可怕的分割错误问题时遇到了一些困难。我用一个数组创建了一个“结构”,并用随机字符填充。从那里我计算水平和垂直对。
在我运行 function3() 之前,一切似乎都很好。从那里出现分段错误。我运行 GDB 来查找错误,但我不知道为什么它不起作用,因为我为 function2() 做了一个类似的函数,并且该函数没问题。我不确定我是否缺少指针。我玩过加减指针,但没有运气。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROW 12
#define COL 15

typedef struct letter_array {
    char** letters;
    struct letter_array *ltr_ptr;
} larray;

void function1 (larray * letter1);
int function2 (larray  * letter2);
int function3 (larray * letter3);
void function4 (int hor_ans, int ver_ans);

int  main ( void )
{  

larray letter_list;
int vert, hori, count;

letter_list.letters = malloc(ROW*sizeof(int*));
for(count = 0; count<ROW; count++)
    {
    letter_list.letters [count] = malloc(COL*sizeof(int));
    }

printf("\n \t\t\t *** Hello! ***");

printf("\n This program will create a random selection of 180 upper-case"
    " characters. \n\n");

function1(&letter_list);

hori = function2(&letter_list);

vert = function3(&letter_list);  //The Problem?

free(letter_list.letters);

return ( 0 ) ;
}    


void function1 (larray *letter1)  // Assign random letters to array.
{
int i, z;

    srandom((unsigned)time(NULL));

for(i=0; i<ROW; i++)
 { 
    for(z=0; z<COL; z++)
    {
    letter1->letters[i][z] = random( )%26+'A';
    printf("%c ", letter1->letters[i][z]);
    }
 printf("\n");
 }

return ;
}

int function2 (larray * letter2)  //Count horizontal pairs.
{
int a,b;
int m=0;
    for(a=0; a<ROW; a++)
    {
       for(b=0; b<COL; b++)
       {
        if (letter2->letters[a][b] == (letter2->letters[a][b+1]))
        m++;
       }
    }

 return (m);
 }


 int function3 (larray * letter3)  //Count vertical pairs.
 {
 int a,b;
 int n=0;
    for (a=0; a<ROW; a++)
    {
       for(b=0; b<COL; b++)
       {
        if (letter3->letters[a][b] == (letter3->letters[a+1][b])) //THE Problem..?
        n++;
       }
    }
return (n);

在 GDB 中...

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400ad8 in function3 (letter3=0x7fffffffd8a0)
xxx                 if (letter3->letters[a][b] == (letter3->letters[a+1][b]))
(gdb) backtrace
#0  0x0000000000400ad8 in function3 (letter3=0x7fffffffd8a0) 
#1  0x000000000040088f in main () 
(gdb) up
#1  0x000000000040088f in main () 
xxx      vert = function3(&letter_list);

感谢您的帮助!

【问题讨论】:

  • 您可能会发现在gdb 中使用“打印”运算符很有帮助。如在print aprint b 中了解循环的iteration 是什么导致了问题......
  • 为什么在分配给letters时使用sizeof(int*)sizeof(int),这是一个char **?为什么你的函数有这么奇怪的通用名称? function1 应该被称为 assignLettersfunction2 应该被称为 countHorzPairs;等
  • 为什么当 a 有最大值 (ROW-1) 时 a+1 会越界,这不是很明显?您在 function2 中遇到了类似的问题,但由于无效值不是指针而侥幸逃脱。

标签: c struct segmentation-fault function-pointers


【解决方案1】:

这很明显。 GDB 会告诉您确切的位置。在你的function3 你做

for (a=0; a<ROW; a++)

然后你尝试访问

letter3->letters[a+1][b]

这里,a+1 导致分段错误(您跑出了数组的边缘)。

【讨论】:

  • letter3-&gt;letters[a+1] 可能不会直接导致段错误 - 它只是返回垃圾。第二个[b] 索引垃圾指针并导致段错误。
  • function2 具有类似的未定义行为(但不会因为@immibis 识别的原因而崩溃)。
  • @immibis - 我想我们说的是同一件事。当你指向垃圾时,返回的值是垃圾;在那个时候,你最终访问不属于你的内存的机会非常高。
  • @immibis 如果它确实指向垃圾,那么为什么不使用结构时类似的程序会工作?我在结构中没有正确使用指针吗?
  • 有时您会避开这些错误,因为您指向的内存恰好包含“合理”值。我建议你学习如何使用valgrind 或一些类似的实用程序——它会告诉你每个内存访问错误,甚至是那些不会导致崩溃的错误。如果你想了解你的代码是如何真正工作的,这是必不可少的。
猜你喜欢
  • 2020-02-17
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多