首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++:为什么我得到这个分段错误(可能发生在main之前?)

C++:为什么我得到这个分段错误(可能发生在main之前?)
EN

Stack Overflow用户
提问于 2014-12-06 10:28:43
回答 1查看 83关注 0票数 0

我刚刚完成了大部分(我想!)我的调试,我的代码现在编译没有任何错误。然而,当我尝试运行它时,它甚至在main的第一行之前就返回了一个segfault!我想知道这是否可能是内存问题,与我的struct定义中的字符串有关,但我甚至还没有初始化它们,所以我不知道它是如何工作的。我想的另一件事是,当我设置字符串时,可能需要使用new运算符,但据我所知,我的书声明字符串的方式与我一样(尽管它们不是结构的一部分……)

不管怎样,这是我的代码!我们应该破解一些(可能非常糟糕的)密码,这些密码都使用相同的盐。

代码语言:javascript
复制
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <crypt.h>
using namespace std;

/* Read in a large, standard dictionary.
   Encrypt each word in the dictionary using the crypt() function
   Read in the password file and check each user's password to see
   whether it matches one of the dictionary entries
   Output the passwords for all of the accounts you have
   broken. */
struct ListNode{
  string user;
  string salt;
  string encrypted;
  string password;
  ListNode* next;
};


int main(){

  cout<<"Hello world\n\n";
  /* Initializes singly linked list to hold user data */
  ListNode *root;
  ListNode *conductor;
  root = new ListNode;
  conductor = root;

  cout<<"After initializing list\n\n";
  string temp;

  //creates and opens filestream to password file
  ifstream psswdFile ("simplepsswd.txt");

  if(psswdFile.is_open()){
    //we assume there is at least one line, and initialize the head of
    //the list
    std::getline(psswdFile, conductor->user, ':');
    std::getline(psswdFile, conductor->salt, ':');
    std::getline(psswdFile, conductor->encrypted);
    //create first node
    //while there's more lines (store username in temp so we can
    //check)
    cout<< "Before password loop\n\n";
    while(std::getline(psswdFile, temp, ':')){
      //create next node
      conductor->next = new ListNode;
      conductor = conductor->next;
      conductor->next = NULL;
      //set data fields
      conductor->user = temp;
      //I know we don't NEED to store the salt but what if you decided
      //you wanted it later
      std::getline(psswdFile, conductor->salt, ':');
      std::getline(psswdFile, conductor->encrypted);
    }
  }

  //open the dictionary file
  ifstream dicFile("/usr/share/myspell/en_US.dic");
  string dicEntry;
  string dicEncrypted;

  if(dicFile.is_open()){
    int loc;
    //loop through words in dictionary
    cout<<"Before dictionary loop\n\n";
    while(std::getline(dicFile, dicEntry)){
      //check for weird flags and whatever.
      int loc = dicEntry.find('/');
      if(loc > 0){
    //if they're there, get rid of them!
    dicEntry.resize(loc);
      }
      //convert the entry to a c-string so we can use crypt on it
      char* cString;
      strcpy(cString, dicEntry.c_str());
      cString = crypt(cString, "AB");
      dicEncrypted = cString;
      //loop through the list comparing to encrypted passwords
      conductor = root;
      if(conductor->encrypted == dicEncrypted){
    conductor->password = dicEntry;
      }
      //password could occur more than once!
      while(conductor->next != NULL){
    conductor = conductor->next;
    if(conductor->encrypted == dicEncrypted){
      conductor->password = dicEntry;
    }
      }
    }
  }
  cout<<"Before print loop\n\n";
  conductor = root;
  if(conductor->password != ""){
    cout << "User " << conductor->user << "'s password is " << conductor->password << "\n\n";
  }
  while(conductor->next != NULL){
    conductor = conductor->next;
    if(conductor->password != ""){
      cout<<"User " << conductor->user << "'s password is " << conductor->password <<"\n\n";
    }
  }
  return 0;
}

好了,我尝试了评论中的一些东西,似乎我一创建我的第一个ListNode就得到了一个段错误!

EN

回答 1

Stack Overflow用户

发布于 2014-12-06 11:40:12

现在的一个问题是你正在写一个未初始化的指针:

代码语言:javascript
复制
  //convert the entry to a c-string so we can use crypt on it
  char* cString;
  strcpy(cString, dicEntry.c_str());
  cString = crypt(cString, "AB");
  dicEncrypted = cString;

cString是一个未初始化的指针,指向谁知道在哪里。然后使用strcpy函数将字符写入此内存地址。这是未定义的行为,最有可能是分段错误。

您必须分配内存,以便strcpy有空间写入字符串(加上终止NULL)。

代码语言:javascript
复制
  char cString[100]; // or whatever number is large enough
  strcpy(cString, dicEntry.c_str());
  cString = crypt(cString, "AB");
  dicEncrypted = cString;

但即使这样也不安全,因为100可能没有足够的空间。您需要post crypt函数来获得一个更健壮的答案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27327665

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档