在C中使用strncat时出现分段错误

时间:2016-08-03 17:14:27

标签: c segmentation-fault

所以我刚开始学习两周,基本上是初学者。所以我写了这个程序。但它在strncat函数中不断给出Segmentation fault错误第41行。我不确定我做错了什么。

#include <stdio.h>
#include <string.h>
#define _XOPEN_SOURCE
#include <unistd.h>

#define _GNU_SOURCE
#include <crypt.h>

#define WORD "/usr/share/dict/words"

int error(void);
int check(char *text, char *psswrd, char *salt);

int main(int argc, char *argv[])
{
    if (argc != 2)
        return error();

    char salt[3]; 
    salt[0] = argv[1][0];
    salt[1] = argv[1][1];
    salt[2] = '\0';

    FILE *fptr;
    char ch;
    char *word;
    int flag = 0;
    fptr = fopen(WORD, "r");
    if (fptr == NULL)
    {
        flag = 1;
    }
    else
    {
        do
        {
            ch = fgetc(fptr);
            if ( ch != ' ' && ch != '\n')
            {
                word = strncat(word, &ch, 1);
                if (strlen(word) == 8)
                {
                    flag = check(word, argv[1], salt);
                    if (flag == 0)
                    {
                        printf ("%s \n", word);
                        return 0;
                    }
                }
            }
            else
            {
                word = "";
            }
        }
        while (ch != EOF);

        fclose(fptr);
    }

    if (flag == 2)
    {
        printf("Password not found\n");
        return 2;
    }
}

int error(void)
{
    printf ("Usage: ./crack <encrypted keyword>\n");
    return 1;
}

int check(char *text, char *psswrd, char *salt)
{
    if (strcmp(crypt(text, salt), psswrd) == 0 )
        return 0;
    else 
        return 2;
 }

3 个答案:

答案 0 :(得分:1)

您需要为“word”分配内存缓冲区:

word = malloc(MaxInputSize);

或者更好的方法是将word声明为静态数组:

word[MaxInputSize];

答案 1 :(得分:1)

char *word;

您已将word声明为指向char的指针,但您尚未设置word指向的位置。只要未分配的word可以指向任何地方并取消引用word,即*word会导致未定义的行为,这正是您在

中所做的
 word = strncat(word, &ch, 1);

为了使代码正常工作,您需要在上述步骤之前将内存分配给word,即执行类似

的操作
word=malloc(100*sizeof *ptr); // You set word to point to a chunk of 100 bytes

假设word指向一个100字节的块,现在

strncat(word, &ch, 1);

逻辑上不正确,因为假设word已完全填充(99个字符加上终止空字符),则无法再添加一个字符,因此在此步骤之前需要进行一些错误检查。做点什么

if strlen(word)<=98)  // remember 99 is the max allowed, you gonna add 1 char
  strncat(word, &ch, 1);

作为一种好的做法,您可以在使用后删除内存,即

free(word);

答案 2 :(得分:1)

您需要为word分配内存,作为数组或使用malloc。如果字符串很小(与堆栈大小相比),请使用数组,因为它不需要清理。

你还需要在word[0]=0;之后设置malloc,否则你会得到垃圾和可能的第二个分段错误。

将字符添加到字符串的规范方法是

char word[9];
char* pWord = word;
memset(word,0,sizeof(word));
...

  ch = getchar();
  *pWord++ = ch;
  len++;
  if (len >= sizeof(word)-1) ...