memcpy(), ошибка сегментации при изменении значения предопределенной переменной
Я написал программу для обработки ввода командной строки. У меня ошибка сегментации во время функции memcpy(), когда в качестве входных данных используются длинные строки.
Вот код:
int main(int argc, char * argv[])
{
// initialize input variables
char inputFileName[] = "sequence.txt"; //default input file name
//check if a different file name is given
for(int i = 0; i < argc-1; i++){
if(string(argv[i])=="-i"){
cerr << "string: " << string(argv[i+1]).c_str() << endl;
cerr << "string size: " << string(argv[i+1]).size() << endl;
inputFileName[string(argv[i+1]).size()]=0;
cerr << "filename: " << inputFileName << endl;
memcpy(inputFileName,string(argv[i+1]).c_str(),string(argv[i+1]).size());
cerr << "filename after memcpy: " << inputFileName << endl;
break;
}
}
}
Когда дается короткое имя файла (-i sequence.fasta), оно работает правильно:
$ ./Program -i sequence.fasta
string: sequence.fasta
string size: 14
filename: sequence.txt
filename after memcpy: sequence.fasta
filename final: sequence.fasta
Однако длинное имя вызывает ошибку сегментации:
$ ./Program -i sequencesequencesequencesequencesequencesequencesequencesequencesequencesequence.fasta
string: sequencesequencesequencesequencesequencesequencesequencesequencesequencesequence.fasta
string size: 86
filename: sequence.txt
Segmentation fault: 11
Я что-то пропустил? Как мне обращаться с memcpy()?
2 ответа
Это ваша проблема:
inputFileName[string(argv[i+1]).size()]=0;
inputFileName имеет предопределенный размер, равный strlen("sequence.txt") + 1 == 12 байт + 1 байт для '\0'
char inputFileName[] = "sequence.txt"; //default input file name
так что если вы индексируете его, используя строку (argv[i+1]).size(), тогда поведение не определено, если argv [i + 1] длиннее 13.
Вы должны использовать std::string в качестве буфера
Помимо этого размер массива
char inputFileName[] = "sequence.txt";
исправлено и равно 13, ваш код имеет еще одну ошибку. Когда вы выполняете memcpy
memcpy(inputFileName,string(argv[i+1]).c_str(),string(argv[i+1]).size());
тогда вы не копируете завершающий ноль, потому что выражение string(argv[i+1]).size()
не принимает это во внимание.