#c #segmentation-fault
#c #ошибка сегментации
Вопрос:
я подписал звездочками 2 строки, которые создают проблему.
первая строка выделяет память для файла журнала, который будет использоваться во второй подписанной строке. во второй строке со знаком возникает проблема с ошибкой сегментации. Это вызвано тем фактом, что «logfile» не выделен. Я уверен в этом, потому что, если я выделяю память в load (), это работает. Однако я хочу выделить память в конструкторе класса, а не в методе load().
Я не могу понять, почему это не работает! Я впервые в Linux, и поэтому, возможно, я делаю что-то не так!
Спасибо, Марко
server::server(){
port = 0;
serverup = 0;
loaded = 0;
logfile = (char *) malloc(SERVER_PATHS_SIZE*sizeof(char)); //****************************
}
int server::load(int in_id, char *in_name, char *in_ip, int in_port,
char *in_rcon, char *in_logfile){
int err;
sprintf(name, "%sx00", in_name);
sprintf(ip, "%sx00", in_ip);
port = in_port;
sprintf(rcon, "%sx00", in_rcon);
sprintf(logfile,"%sx00", in_logfile); //**********************************
err = urt.set(ip, port, rcon);
if(err < 1){
printf("server::load(): error from urt.set()n");
return 0;
}
printf("server::load(): server %d loaded!n", id);
loaded = 1;
return 1;
}
Комментарии:
1. Пожалуйста, сократите свой код до рабочего (т.е. компилируемого, пригодного для выполнения) примера, который демонстрирует проблему. В противном случае мы можем только догадываться, в чем проблема…
2. Мы не можем видеть, где
logfile
объявлено. Является ли это переменной-членом класса server? Является ли это глобальным? Создание возможности автономной компиляции ваших примеров имеет решающее значение для отладки.3. при программировании c
new
обычно предпочтительнее, чемmalloc
4. По какой-либо конкретной причине вы не используете
std::string
?5. Рассмотрите возможность удаления тега «linux» из этого раздела, поскольку он не имеет ничего общего с Linux.
Ответ №1:
Я думаю, вы пытаетесь выполнить nullterminate in_logfile
и in_rcon
Это не будет работать с printf, потому что для printf в первую очередь требуется строка с нулевым завершением в качестве аргументов для %s.
charptr[known_length] = 0
вместо
Комментарии:
1. Чтобы немного упростить, ошибка сегментации возникает из-за того, что отсутствие нулевого завершения в исходном вводе на
sprintf
приводит к считыванию данных после окончания исходного ввода, что приводит к недопустимому чтению. Кроме того, затем вы пытаетесь присвоить выходным массивам намного больше данных, чем вы думаете, что приводит к недопустимым записям.
Ответ №2:
Это определенно не ответ, но разработка на C поможет вам избежать проблем с памятью, которые возникают при использовании кода C-with-classes.
Используйте std::strings, тогда их копирование будет тривиальным (по сравнению со sprintf), и это будет намного безопаснее. Использование устаревшего символа char * приводит к путанице.
Приятным побочным эффектом является то, что вам не нужно будет вручную выделять память (с помощью malloc или new) и устранять любой риск утечки памяти.
Комментарии:
1. Использование
char*
для обработки символьных массивов не рекомендуется. (Хотя привязка строковых литералов кchar*
, а неchar const*
является.)
Ответ №3:
-
Я не вижу деструктора класса server. У вас есть деструктор, который освобождает память?
-
Я не вижу кода, который создает и использует серверный объект. Может ли быть так, что вы создаете объект server, но затем делаете его копию, и проблема возникает из-за того, что вы неправильно реализуете семантику копирования?
Комментарии:
1. (2) Нет, это невозможно из-за (1). 🙂
2. Темный сокол, ты гений!! В этом и заключалась проблема!! Большое спасибо!
3. В принципе, конструктор не был вызван … вероятно, я создавал объект сервера неправильным способом! спасибо всем за ответы!