与文件i/o相关的c++程序末尾的Segfault
Segfault at end of c++ program related to file i/o
我正在进行一个密码学项目,我们的密码需要能够读取和写入文件。我的一个合作伙伴实现了阅读功能,现在我们遇到了一个奇怪的问题。如果用户没有提供输出文件,我们的程序会正确运行,没有错误,但如果提供了输出文件,则会在完成后(返回0)出现segfault。然而,程序只在我的机器上出现故障。我的团队成员运行的是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)
感谢您的帮助!
这是你给自己带来悲伤的地方:
out.open(outputFile);
std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
std::cout.rdbuf(out.rdbuf());
现在有两个对象都指向同一个buf。猜猜一个对象被破坏并清理了它的资源,然后第二个对象开始执行析构函数后会发生什么。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- C++,系统无法执行指定的程序
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 重载操作程序时出错>>用于类中的字符串 memebr
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 试图在visual studio上用C++创建一个桌面应用程序
- 模板元程序查找相似的连续类型名称
- FFmpeg:制作一个应用程序比直接使用ffmepg更好吗
- 如何通过cpp程序运行shell脚本
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- IPC使用多个管道和分支进程来运行Python程序
- 如何将c++程序的一些输出传递给shell,以便在shell中使用
- 使用C++程序合并排序没有得到正确的输出
- 基于boost的程序的静态链接——zlib问题
- 程序崩溃并显示"std::out_of_range"错误
- 在C应用程序中运行C++(带有STL)函数
- 使用mongocxx驱动程序时包含头文件问题
- 如何在c++程序中找到函数的地址