проблема с выделением памяти в Linux

#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:

  1. Я не вижу деструктора класса server. У вас есть деструктор, который освобождает память?

  2. Я не вижу кода, который создает и использует серверный объект. Может ли быть так, что вы создаете объект server, но затем делаете его копию, и проблема возникает из-за того, что вы неправильно реализуете семантику копирования?

Комментарии:

1. (2) Нет, это невозможно из-за (1). 🙂

2. Темный сокол, ты гений!! В этом и заключалась проблема!! Большое спасибо!

3. В принципе, конструктор не был вызван … вероятно, я создавал объект сервера неправильным способом! спасибо всем за ответы!