C:在查找功能名称时分段故障(核心倾倒)



我想编写一个C代码以查找C文件中的所有函数并打印相应的函数名称。

我的代码是:

#include <stdio.h>
#include <string.h>
#define SIZE 1024
void ffname(char *line)
{
    int i=1,j=0;
    char *dt; 
    char *name;
    strtok(line,"("); 
    dt = strchr(line,' '); 
    if(dt[i] == '*')
        i++;
    while(dt[i] != '')
    {
        name[j]=dt[i];
        i++;
        j++;
    }
    name[j] ='';
    printf("Function name is: %sn", name);
}
int main(int argc, char **argv)
{
    if(argc < 2)
    {
        printf("Give the filename n");
        printf("Usage: %s filenamen", argv[0]);
        return -1;
    }
    int i, lines =0, funlines =0,count =0, fn =0, flag =0;
    char c[100],b[100];
    FILE *fd;
    fd = fopen(argv[1],"r");
    while(fgets(c,SIZE,fd))
    {   
        lines++;
        i=0;
        for(i=0;i<strlen(c);i++)
        {
            while( c[i] =='t' || c[i] == ' ')
            {
                i++;
            }
            if( c[i] == '{')
            {
                count++;
                if(flag)
                {
                    funlines++;
                }
                if(count == 1)
                {
                    fn++;
                    printf("Function %d is Started..............n", fn); 
                    flag = 1;
                    ffname(b);
                }
                break;
            }
            else if( c[i] == '}')
            {
                count--;
                if(!count)
                { 
                    flag = 0;
                    printf("No of lines in the function %d is: %dn", fn, funlines);
                    printf("Function %d is finished..........n", fn);
                    funlines = 0;
                }
                else
                {
                    funlines++;
                }
                break;
            }
            else if(flag)
            {
                funlines++;
                break;
            }
        }
        strcpy(b,c);
    }
    printf("Total no of fucnion%dn",fn);
    printf("Total no of lines%dn",lines);
    return 0;
}

当我将以下C文件作为输入时,

#include<stdio.h>
void add()
{
    int a=5,b=7;
    printf("Addition is:%dn", a+b);
}
void sub()
{
    int a=20,b=8;
    printf("Subtraction is:%dn", a-b);
}
void main()
{   
    char *name="dhahira dhasneem";
    char *line;
    line=strchr(name,' ');
    printf("Line:%sn",line);
    printf("Name:%sn",name);
    add();
    sub();
}

我得到以下输出。

Function 1 is Started..............
Segmentation fault (core dumped)

我使用valgrind,但我不知道如何识别错误。请引导我。谢谢。

更新:

当我使用建议的答案时,我得到了输出。之后,我想将以前的代码扩展为将功能(功能名称和功能深度)的详细信息存储到结构中。当我用来存储简单程序的功能详细信息时,我正在获得输出。但是我在程序中收到以下输出,当我在 gdb中运行。

(gdb) b 87
Breakpoint 1 at 0x804885e: file fun_printstruct.c, line 87.
(gdb) r dat.c
Starting program: /home/dhahira/dhas/Project/a.out dat.c
Function 1 is Started..............
Program received signal SIGSEGV, Segmentation fault.
0x080485d4 in ffname (line=0xbfffe71c "/*struct *dhahira", name=0x0)
    at fun_printstruct.c:21
21          name[j]=dt[i];
(gdb) s
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.

我的代码是:(扩展以将功能详细信息存储到结构中)

#include <stdio.h>
#include <string.h>
#define SIZE 1024
void ffname(char *line)
{
    int i=1,j=0;
    char *dt; 
    char name[SIZE];
    strtok(line,"("); 
    dt = strchr(line,' '); 
    if(dt[i] == '*')
        i++;
    while(dt[i] != '')
    {
        name[j]=dt[i];
        i++;
        j++;
    }
    name[j] ='';
    printf("Function name is: %sn", name);
}
int main(int argc, char **argv)
{
    if(argc < 2)
    {
        printf("Give the filename n");
        printf("Usage: %s filenamen", argv[0]);
        return -1;
    }
    int i, lines =0, funlines =0,count =0, fn =0, flag =0, fg=0,size=0,emptyflag=0,commandflag=0;
    char c[SIZE],b[SIZE],st[SIZE],d[SIZE];
    int command[]={};
    FILE *fd;
    fd = fopen(argv[1],"r");
    while(fgets(c,SIZE,fd))
    {
        emptyflag=0;    
        lines++;
        for(i=0;i<(sizeof(command)/4);i++)
        {
            if(lines == command[i])
            {
                commandflag=1;
                break;
            }   
        }
        strcpy(st,c);
        strtok(st," ");
        size = strlen(c);
        if(size == 1 && (strcmp(c,"n"))== 0)
            emptyflag=1;
        if( !strcmp(st,"struct")) 
            fg=1;
        for(i=0;i<size;i++)
        {
            if(commandflag)
            {
                break;
            }   
            while( c[i] =='t' || c[i] == ' ')
            {
                i++;
            }
            if( c[i] == '{')
            {
                count++;
                if(flag)
                {
                    if(!emptyflag)
                        funlines++;
                    else
                        emptyflag=0;
                }
                if(count ==1 && fg ==1)
                {
                    if(b[strlen(b)-2] == ')')
                    {
                        fn++;
                        printf("Function %d is Started..............n", fn); 
                        flag = 1;
                        ffname(b);
                    }   
                    else
                    {
                        count--;
                    }   
                }
                else if(count == 1)
                {
                    fn++;
                    printf("Function %d is Started..............n", fn); 
                    flag = 1;
                    ffname(b);
                }
                break;
            }
            else if( c[i] == '}')
            {
                count--;
                if(count ==0 && fg ==1)
                { 
                    flag = 0;
                    printf("No of lines in the function %d is: %dn", fn, funlines);
                    printf("Function %d is finished..........n", fn);
                    funlines = 0;
                    fg=0;
                }
                else if(count ==0)
                {
                    flag = 0;
                    printf("No of lines in the function %d is: %dn", fn, funlines);
                    printf("Function %d is finished..........n", fn);
                    funlines = 0;
                }
                else if(count == -1)
                {
                    count=0;
                    fg=0;
                }
                else 
                {
                    if(!emptyflag)
                        funlines++;
                    else
                        emptyflag=0;
                }
                break;
            }
            else if(flag ==1 && fg==1)
            {
                if(!emptyflag)
                    funlines++;
                else
                    emptyflag=0;
                break;
            }
            else if(flag)
            {
                if(!emptyflag)
                    funlines++;
                else
                    emptyflag=0;
                break;
            }
            break;
        }
        if(commandflag == 1)
            commandflag = 0;
        else
            strcpy(b,c);
    }
    printf("Total no of fucnion%dn",fn);
    printf("Total no of lines%dn",lines);
    return 0;
}

请指导我克服这个问题。

由于扩展了代码,这个问题是否来了?(我可以分开获得正确的输出。)

您将SIZE声明为1024,然后读取为长度100:

#define SIZE 1024
// ... snip ....
    char c[100],b[100];
    FILE *fd;
    fd = fopen(argv[1],"r");
    while(fgets(c,SIZE,fd))

这意味着您在数组的界限,堆栈的其余部分中写得很好,并导致腐败。在这种情况下,这可能实际上并没有发生,因为您的输入文件中的行均不到100个字符,但是如果有人通过长行中的文件传递。

这应该是

    char c[SIZE],b[SIZE];

或在fgets()中使用sizof()

fgets(c,sizeof(c),fd)

正如其他人指出的那样,最好打开所有可用警告;这将帮助您更快地捕获错误。在GCC或Clang中,我建议-Wall -Wextra -Werror;这将使所有常见的警告能够将警告视为错误,因此您不能忽略它们。如果我在您的代码上运行它,我也会收到以下警告:

sf.c:16:9: error: variable 'name' is uninitialized when used here
      [-Werror,-Wuninitialized]
        name[j]=dt[i];
        ^~~~
sf.c:9:15: note: initialize the variable 'name' to silence this warning
    char *name;
              ^
               = NULL
sf.c:40:18: error: comparison of integers of different signs: 'int' and 'size_t'
      (aka 'unsigned long') [-Werror,-Wsign-compare]
        for(i=0;i<strlen(c);i++)
                ~^~~~~~~~~~

第二个不是一个严重的问题,只需将其施放或声明i未签名;您应该第一个修复。您需要在堆栈(char name[SIZE];或类似)或动态(char *name = malloc(strlen(line));或类似的东西)上分配一个名称的缓冲区。实际上,name是一个非初始化的指针。它可以指向内存中的任何位置,一旦您尝试通过在name[j]中存储某些内容来将其删除,您就会写入无效的内存区域并获得segfault。

最后,一旦解决了这些问题,如果您遇到了其他问题,我建议在调试器下运行它,并查看问题发生在哪里。如果您使用的是IDE,它可能内置了一个调试器接口;如果不是,则使用-g编译,然后运行gdb executable arguments

相关内容

  • 没有找到相关文章

最新更新