我正在加密项目,我们的密码需要能够读取和写入文件。我的一个合作伙伴实现了阅读能力,现在我们遇到了一个奇怪的问题。如果用户没有提供输出文件,我们的程序正确运行且没有错误,但是如果提供了输出文件,则在完成后返回段错误(返回0)。但是程序只能在我的机器上发生段错误。我的团队成员正在运行OS X和Fedora,而我正在运行Ubuntu,如果这很重要的话。我们所有人都在使用c ++ 11进行编译,尽管我在技术上指定了c ++ 0x。
int main(int argc, char** argv)
{
std::string usageWarning = "usage: [-i/--input fileName] [-o/--output fileName]
[- k/--key 32bitKey] [-n/--nonce numEncryptions]";
int nonce = 1;
std::string inputFile;
std::string outputFile;
std::string key;
bool hasInputFile = false;
bool hasOutputFile = false;
bool hasKey = false;
std::ofstream out;
if (argc < 2) {
std::cerr << usageWarning << std::endl;
return 1;
}
//Parse command line input
for( int i = 1; i < argc; i++ ) {
if (0 == strncmp(argv[i], "-n", 2) || 0 == strncmp(argv[i], "--nonce", 7)) {
i = i + 1;
nonce = std::stof(argv[i]);
}
else if (0 == strncmp(argv[i], "-i", 2) || 0 == strncmp(argv[i], "--input", 7)) {
i = i + 1;
inputFile = argv[i];
hasInputFile = true;
}
else if (0 == strncmp(argv[i], "-o", 2) || 0 == strncmp(argv[i], "--output", 8)) {
i = i + 1;
outputFile = argv[i];
out.open(outputFile);
std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
std::cout.rdbuf(out.rdbuf());
hasOutputFile = true;
}
else if (0 == strncmp(argv[i], "-k", 2) || 0 == strncmp(argv[i], "--key", 5)) {
i = i + 1;
key = argv[i];
hasKey = true;
}
else {
std::cerr << "Unrecognized option." << std::endl;
std::cerr << usageWarning << std::endl;
return 1;
}
}
Serpent serpent;
unsigned char testKey[] = {0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
unsigned char plaintext[16] =
{0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
if (hasKey) {
unsigned char new_key[32];
int index = 0;
for (int i = 0; i < key.length() - 2; i++) {
std::stringstream ss;
ss << std::hex << key[i] << key[i+1];
int n;
ss >> n;
unsigned char x = (unsigned char)n;
new_key[index] = x;
index += 1;
i += 1;
}
memcpy(testKey, new_key, sizeof(testKey));
}
if (hasInputFile) {
unsigned char new_plaintext[16];
std::ifstream in(inputFile);
unsigned char x;
int index = 0;
std::string temp_string = "";
while (in >> std::noskipws >> x) {
std::cout << "X: " << std::hex << x << std::endl;
temp_string += x;
if (temp_string.length() == 2) {
std::stringstream ss;
ss << std::hex << temp_string;
int n = 0;
ss >> n;
unsigned char y = (unsigned char)n;
new_plaintext[index] = y;
index += 1;
temp_string = "";
}
}
// Set plaintext to be theplaintext we read in from file
memcpy(plaintext, new_plaintext, sizeof(plaintext));
}
else {
}
serpent.setKeySize(sizeof(testKey)/sizeof(*testKey));
serpent.setKey(testKey);
serpent.generateSubKeys();
std::cout << "TESTING" << std::endl;
int encryptionRound = 0;
while (encryptionRound < nonce) {
std::cout << std::dec << "================================ ROUND <<
encryptionRound << " ================================\n" << std::endl;
serpent.encrypt(plaintext);
std::cout << std::dec << "============================ END ROUND " <<
encryptionRound << " ============================\n"<< std::endl;
encryptionRound++;
}
if (hasOutputFile){
out.close();
}
return 0;
}
我跑了Valgrind并获得了以下输出,但我对io业务缺乏经验,并且不知道如何处理这些信息。
==3131== Memcheck, a memory error detector
==3131== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==3131== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==3131== Command: ./SerpentOpt -n 1 -o output.txt
==3131==
==3131== Invalid read of size 8
==3131== at 0x4EC7328: std::ostream::flush() (in /usr/lib/x86_64-
linux gnu/libstdc++.so.6.0.16)
==3131== by 0x4E97F9B: std::ios_base::Init::~Init() (in /usr/lib/x86_64-linux-
gnu/libstdc++.so.6.0.16)
==3131== by 0x5385900: __run_exit_handlers (exit.c:78)
==3131== by 0x5385984: exit (exit.c:100)
==3131== by 0x536B773: (below main) (libc-start.c:258)
==3131== Address 0x7fefffd88 is just below the stack ptr. To suppress, use: --
workaround-gcc296-bugs=yes
==3131==
==3131==
==3131== Process terminating with default action of signal 11 (SIGSEGV)
==3131== Bad permissions for mapped region at address 0x4224580
==3131== at 0x4224580: ??? (in /lib/x86_64-linux-gnu/ld-2.15.so)
==3131== by 0x4EC732D: std::ostream::flush() (in /usr/lib/x86_64-linux-
gnu/libstdc++.so.6.0.16)
==3131== by 0x4E97F9B: std::ios_base::Init::~Init() (in /usr/lib/x86_64-linux-
gnu/libstdc++.so.6.0.16)
==3131== by 0x5385900: __run_exit_handlers (exit.c:78)
==3131== by 0x5385984: exit (exit.c:100)
==3131== by 0x536B773: (below main) (libc-start.c:258)
==3131==
==3131== HEAP SUMMARY:
==3131== in use at exit: 0 bytes in 0 blocks
==3131== total heap usage: 10,745 allocs, 10,745 frees, 493,629 bytes allocated
==3131==
==3131== All heap blocks were freed -- no leaks are possible
==3131==
==3131== For counts of detected and suppressed errors, rerun with: -v
==3131== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
感谢您的帮助!
答案 0 :(得分:2)
这就是你让自己陷入悲痛的地方:
out.open(outputFile);
std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
std::cout.rdbuf(out.rdbuf());
现在有两个对象都指向同一个buf。猜猜一个对象被销毁后会发生什么,清理它的资源,然后第二个对象开始做它的析构函数。