C程序段错误(核心转储)

标签 c gcc

我有一个基本程序,它通过 readline 函数接收用户命令 "command varname = variable"。然后它解析字符串以将每个部分存储到一个字符串变量中。我遇到的问题是出现错误:segmentation default (core dumped) 这应该是来自非法内存访问,但是我已经在示例输入上逐行检查我的程序:"set ray" 我无法弄清楚这是在哪里发生的。我的预期结果是 Command 应该包含 set,Varname 应该包含 ray,Value 应该是 NULL 这是代码以及显示错误的示例输入和输出。我还看到一个错误:bus (core dumped) show up once。知道这个错误是从哪里来的吗?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <readline/readline.h>
#include <readline/history.h>

/* Simple example of using gnu readline to get lines of input from a user.
   Needs to be linked with -lreadline -lcurses
   add_history tells the readline library to add the line to it's
   internal histiry, so that using up-arrow (or ^p) will allows the user
   to see/edit previous lines.
*/


int main(int argc, char **argv) {

  char * s;
  char * Command;
  char * Varname;
  char * Value;

  while (s=readline("Enter Name: ")) {
    add_history(s); /* adds the line to the readline history buffer */

    printf("Hello %s\n",s);/*output message to the user*/

    int part = 1;
    int i;

    for (i = 0; i < strlen(s); i++)
      {

        while((isspace(s[i]) || s[i] == '=') && (i < strlen(s)))
          {
            i++;//parse the string for the next portion of the command            
          }

        if(i >= strlen(s))
          {
            printf("Error: Command not properly formatted!\n");
            break;//terminate the for loop
          }        

        if(part == 1)//grab the command
          {
            int size1 = 0;//size of the command
            int j = i;//index of the first non-space character in this portion of the string

            while(!isspace(s[j]))//determine the size of the command, j will point to space when the loop exits
              {
                size1++;
                j++;                            
              }

            Command = (char*) malloc (size1+1);//allocate space to hold the characters of the command along with the terminating '\0' character

            int d = 0;//destination index
            while(i<j)
              {
                Command[d] = s[i];//copy the characters of the command portion of s over to the command array
                d++;
                i++;
              }

            Command[d] = '\0';//terminating null character
            part++;//increment the part of the command

          }
        else if(part == 2)//grab the varname
          {
            int size2 = 0;//initialize the size of the character array which will hold the variable name
            int k = i;
            while(!isspace(s[k]))//determine the size of the varname, k will be at the next space when the loop exits
              {
                size2++;
                k++;                            
              }

            Varname = (char*) malloc (size2+1);//allocate space to hold the characters of the Varname along with the terminating '\0' character

            int e = 0;
            while(i<k)
              {
                Varname[e] = s[i];//copy the characters of the Varname portion of s over to the Varname string
                e++;
                i++;
              }
            Varname[e] = '\0';
            part++;//increment part
          }
        else if(part == 3)//grab the value if one is given
          {
            int size3 = 0;//initialize the size of the character array which will hold the value of the environment variable
            int l = i;
            while(!isspace(s[l]) && s[l] != '\0')//determine the size of the varname and check if we've reached the end of the string
              {
                size3++;
                l++;                            
              }

            Value = (char*) malloc (size3+1);//allocate space to hold the characters of the Value along with the terminating '\0' character
            int f = 0;
            while(i<l)
              {
                Value[f] = s[i];//copy the characters of the command portion of s over to the command array
                f++;
                i++;
              }
            Value[f] = '\0';
          }
      }
    /*print out the sections of the full command*/
    if(Command != NULL)
      {
        printf("Hey %s\n",Command);
      }
    if(Varname != NULL)
      {
        printf("Hey %s\n",Varname);
      }  
    if(Value != NULL)
      {
        printf("Hey %s\n",Value);
      }

    /* clean up! */
    free(s);
    free(Command);
    free(Varname);
    free(Value);
  }
  return(0);
}

示例输入/输出:

Enter Name: set ray = 21
Hello set ray = 21
Hey set
Hey ray
Hey 21
Enter Name: print ray
Hello print ray
Hey print
Hey ray
Hey
Enter Name: delete varname
Hello delete varname
Hey delete
Hey varname
Hey delete
Enter Name: print raymond
Hello print raymond
Hey print
Hey raymond
Hey
Enter Name: delete variable
Hello delete variable
Hey delete
Hey variable
Segmentation fault (core dumped)

最佳答案

你声明了三个指针但没有初始化它们

char * Command;
char * Varname;
char * Value;

根据用户输入的内容,这些可能不会全部初始化为指向 for 循环内动态分配的内存。如果它们没有全部初始化,稍后尝试释放它们可能会崩溃

free(Command);
free(Varname);
free(Value);

最简单的解决方法是在开始处理每一行时将所有变量初始化为NULL

while (s=readline("Enter Name: ")) {
    Command = NULL;
    Varname = NULL;
    Value = NULL;

然后可以安全地调用它们的 free,即使它们仍然设置为 NULL

关于C程序段错误(核心转储),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19339086/

相关文章:

c - 在 UDP 套接字上监听,同时还使用 C 从标准输入接收输入

c - getchar()转化为一维数组的难点

c - 编译时如何处理lib依赖?

在 c 中返回引用时编译器错误,但在 c++ 中有效

c - 编译某些 ffmpeg 应用程序时出现 gcc 奇怪的 ld 错误,找不到 libvorbisenc 包

c - 使用 GetFileVersionInfo 和 VerQueryValue 获取 Windows 10 的完整版本号时出现问题

c - 从 8 位值转换时如何对 9 位值进行符号扩展?

c - 在 C 中打印字母金字塔

Linux 海湾合作委员会 : How to write a quick function to corrupt the stack?

c++ - 在 CentOS 8 中安装旧的 gcc/g++ 版本