字符串转换的分段错误?
Segmentation Fault on string conversion?
我正在从事一个加密项目,我正在做一个简单的测试,从终端获取一个文件名并运行我的加密。我有以下加密代码,但出现以下分段错误:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid<br><br>
Program received signal SIGABRT, Aborted.
0x00007ffff74ab428 in __GI_raise (sig=sig@entry=6)
at ../sysdeps/unix/sysv/linux/raise.c:54
54 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
在 运行 与 gdb 的跟踪之后,我已确认此故障是在以下 loc 之后触发的:
string plain(reinterpret_cast(fileContents), fileLength);
我下面的主要函数调用了这段代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <fstream>
#include <limits>
#include <sstream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "rc4_enc.c"
#include "rc4_skey.c"
using namespace std;
void foo(int);
int main(int argc, char * argv[]){
if(argc!=2){
cout << "Please enter the filename that you want to encrypt or decrypt\n";
exit(2);
}
int fd;
fd = open(argv[1], O_RDONLY);
cout << "The file descriptor is " << fd << endl;
//close(fd);// Can I modify it if it's closed?
foo(fd);
return 0;
}
而函数如下:
void foo(int fd) {
int fileLength = lseek(fd, 0, SEEK_END);
unsigned char* fileContents;
fileContents = (unsigned char*) calloc(fileLength, sizeof(char));
pread(fd, fileContents, fileLength, 0);
string plain(reinterpret_cast<char*>(fileContents), fileLength); // Segfault happens here. But why?
RC4_KEY key;
int length = plain.size();
unsigned char *buf = (unsigned char*)malloc(length+1);
memset(buf, 0, length+1);
ifstream pass;
pass.open("pass.txt");
if(!pass.good()){
return;
}
else{
string password;
getline(pass,password);
RC4_set_key(&key, password.length(), (const unsigned char*)password.c_str());
}
RC4(&key, length, (const unsigned char*)plain.c_str(), buf);
string result((char*)buf, length);
free(buf);
const char *outputBuf = result.c_str();
pwrite(fd, outputBuf, result.length(), 0);
ftruncate(fd, result.length());
}
我会把它留作评论,但没有足够的声誉。
文件有多大? calloc 会不会失败并且 returning NULL?
即使不是那样,检查 calloc 的 return 值也可能是明智的。或者使用 new 运算符,使用 try/catch.
我正在从事一个加密项目,我正在做一个简单的测试,从终端获取一个文件名并运行我的加密。我有以下加密代码,但出现以下分段错误:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid<br><br>
Program received signal SIGABRT, Aborted.
0x00007ffff74ab428 in __GI_raise (sig=sig@entry=6)
at ../sysdeps/unix/sysv/linux/raise.c:54
54 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
在 运行 与 gdb 的跟踪之后,我已确认此故障是在以下 loc 之后触发的:
string plain(reinterpret_cast(fileContents), fileLength);
我下面的主要函数调用了这段代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <fstream>
#include <limits>
#include <sstream>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "rc4_enc.c"
#include "rc4_skey.c"
using namespace std;
void foo(int);
int main(int argc, char * argv[]){
if(argc!=2){
cout << "Please enter the filename that you want to encrypt or decrypt\n";
exit(2);
}
int fd;
fd = open(argv[1], O_RDONLY);
cout << "The file descriptor is " << fd << endl;
//close(fd);// Can I modify it if it's closed?
foo(fd);
return 0;
}
而函数如下:
void foo(int fd) {
int fileLength = lseek(fd, 0, SEEK_END);
unsigned char* fileContents;
fileContents = (unsigned char*) calloc(fileLength, sizeof(char));
pread(fd, fileContents, fileLength, 0);
string plain(reinterpret_cast<char*>(fileContents), fileLength); // Segfault happens here. But why?
RC4_KEY key;
int length = plain.size();
unsigned char *buf = (unsigned char*)malloc(length+1);
memset(buf, 0, length+1);
ifstream pass;
pass.open("pass.txt");
if(!pass.good()){
return;
}
else{
string password;
getline(pass,password);
RC4_set_key(&key, password.length(), (const unsigned char*)password.c_str());
}
RC4(&key, length, (const unsigned char*)plain.c_str(), buf);
string result((char*)buf, length);
free(buf);
const char *outputBuf = result.c_str();
pwrite(fd, outputBuf, result.length(), 0);
ftruncate(fd, result.length());
}
我会把它留作评论,但没有足够的声誉。
文件有多大? calloc 会不会失败并且 returning NULL? 即使不是那样,检查 calloc 的 return 值也可能是明智的。或者使用 new 运算符,使用 try/catch.