С c
не инициализирован, sprintf
пишет в неизвестное место памяти, что приводит к неустановленный поведению. Он может немедленно сработать, он может вообще не сбой, или он может упасть на какую-то совершенно несвязанную строку кода.
Нужно инициализировать указатель, выделив ему память malloc
.
char* get_address_string(PACKAGE* pkg){
char *c = malloc(20); // enough room for output as 00:11:22:33:44:55 plus null terminator
if (c == null) {
perror("malloc failed");
exit(1);
}
sprintf(c, "%02x:%02x:%02x:%02x:%02x:%02x", pkg->address[0], pkg->address[1], pkg->address[2], pkg->address[3], pkg->address[4], pkg->address[5]);
return c;
}
Обратите внимание, что даже если вы знаете заранее, сколько памяти вам нужно, вы не можете установить его в сторону во время компиляции с помощью массива. Это неправильно:
char* get_address_string(PACKAGE* pkg){
char c[20]; // allocated on the stack, contents unspecified on return
sprintf(c, "%02x:%02x:%02x:%02x:%02x:%02x", pkg->address[0], pkg->address[1], pkg->address[2], pkg->address[3], pkg->address[4], pkg->address[5]);
return c;
}
Как это:
char* get_address_string(PACKAGE* pkg){
char c[20]; // allocated on the stack, contents unspecified on return
char *p = c;
sprintf(p, "%02x:%02x:%02x:%02x:%02x:%02x", pkg->address[0], pkg->address[1], pkg->address[2], pkg->address[3], pkg->address[4], pkg->address[5]);
return p;
}
Поскольку c
выделяется в стеке, когда get_address_string
возвращает содержимое не указано, что снова приводит к неустановленному поведению.
Прежде всего это ** должно ** сбой, потому что вы пишете нераспределенную память, отменяя неинициализированный указатель. Надлежащим образом? Трудно дать правило * общего *. Как и вы, вы оставляете ответственность за освобождение памяти от вызывающего (но вы ее выделяете), она * может * быть склонной к ошибкам и причиной утечек. Другой способ - иметь выходной буфер в качестве входного аргумента. Часто он имеет лучшую производительность (буферы могут быть повторно использованы или даже оставаться в стеке), он менее подвержен ошибкам, но он также менее * естественный * и более подробный. –
«Код работает нормально». - Это не реально. –
Во-первых, он 100% не падает. Однако наличие выходного буфера в качестве входного файла должно работать для того, что мне нужно. – mstagg