Конкатенация строк и int приводит к ошибке сегментации в C
Я не уверен, что я делаю неправильно. Я пытаюсь объединить hostname
с pid
создавать id
,
char *generate_id(void) {
int ret;
char id[1048];
char hostname[1024];
pid_t pid = getpid();
//hostname[1023] = '\0';
if ((ret = gethostname(hostname,1024) < 0)) {
perror("gethostname");
exit(EXIT_FAILURE);
}
sprintf(id, "%s%d", pid);
printf("hostname is %s\n", hostname);
printf("The process id is %d\n", pid);
printf("The unique id is %s", id);
return id;
}
РЕДАКТИРОВАТЬ:
Обновленный код после прочтения некоторых ответов:
char *generate_id(void) {
int ret;
char hostname[1024];
pid_t pid = getpid();
//hostname[1023] = '\0';
if ((ret = gethostname(hostname,1024) < 0)) {
perror("gethostname");
exit(EXIT_FAILURE);
}
int size = snprintf(NULL, 0, "%s%d", hostname, pid);
char * id = malloc(size + 1);
printf("hostname is %s\n", hostname);
printf("The process id is %d\n", pid);
printf("The unique id is %s\n", id);
return id;
}
РЕДАКТИРОВАТЬ:
Рабочий код:
char *generate_id(void) {
int ret;
char hostname[1024];
pid_t pid = getpid();
//hostname[1023] = '\0';
if ((ret = gethostname(hostname,1024) < 0)) {
perror("gethostname");
exit(EXIT_FAILURE);
}
int size = snprintf(NULL, 0, "%s%d", hostname, pid);
char * id = malloc(size + 1);
sprintf(id, "%s%d", hostname, pid);
printf("hostname is %s\n", hostname);
printf("The process id is %d\n", pid);
printf("The unique id is %s\n", id);
return id;
}
3 ответа
Проблема с вашей строкой формата:
sprintf(id, "%s%d", pid);
Ваша строка формата имеет два форматера (%s
для строки и %d
для int
), но вы только проходите pid_t
, Вы, вероятно, имеете в виду:
sprintf(id, "%s%d", hostname, pid);
или же
sprintf(id, "%d", pid);
В вашем коде %s
интерпретирует pid
в качестве указателя. Попытка разыменования того, что форматирование строки вызывает ошибку сегментации, так как это недопустимое значение указателя.
Проблема с управлением памятью:
Но в вашем коде также есть неопределенное поведение: вы объявляете id
быть массивом, выделенным стеком, но вы возвращаете этот массив (который здесь распадается на указатель). Это также неправильно и может привести к сбою в дальнейшем.
Вам нужно изменить id
в выделенный массив кучи, как это:
char * id = malloc(1024);
Вызывающий ваш generate_id
Функция тогда должна free
память, когда это сделано.
Это, вероятно, хорошая идея, чтобы выделить только то место, которое вам нужно. Ты можешь использовать snprintf
за что вот так:
// Determine how much space the string needs.
int size = snprintf(NULL, 0, "%d", pid);
// Allocate the required space plus NULL termination.
char * id = malloc(size + 1);
// Actually print the string.
sprintf(id, "%d", pid);
Не знаю, где вы находитесь, но у вас есть несколько проблем.
snprintf () намного безопаснее и не будет переполнять буфер id[]. sprintf может переполнить буфер
sprintf(id, "%s%d", pid) неверен, как упомянуто выше.
return id неверен, так как возвращает указатель на значение в стеке. Как только вы вернетесь, стек больше не ваш.
sprintf(id, "%s%d", pid);
У вас есть два селектора%s и%d, но только один параметр (pid). Вам нужно вставить строку и целое число вместо целого числа.