我有以下代码:
char* get_address_string(PACKAGE* pkg){
char *c;
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;
}
Run Code Online (Sandbox Code Playgroud)
代码工作正常.但是,我知道这不是在C中返回字符串的正确方法.我收到警告"c在此函数中使用未初始化".
在C中编写此函数的正确方法是什么?
"在C中返回字符串的正确方法"并非真正可行.在C中,字符串是一个字符数组(直到并包括空字符),并且数组本身不能从函数返回.
函数可以返回指针.所以通常的方法是"返回一个字符串":
返回一个指针. char *foo1(...)喜欢char *strdup()
传入指向字符数组的指针并修改其内容.void foo2(char *,...)喜欢int sprintf(char *dest, const char *format, ...)
结合1和2之char *foo3(char *, ...) 类的char *strcpy(char *dest, char *src)
传递指针的地址并更新它.foo4(char **ptr)喜欢ssize_t getline(char **lineptr, size_t *n, FILE *stream)
关键是在函数完成后,与指针关联的内存必须有效.返回指向函数的非静态内存的指针是未定义的行为.成功的方法包括让调用代码在指针中传递,或者通过内存分配指向一些持久值(如全局变量或字符串常量)的函数来提供它.
在C中编写此函数的正确方法是什么?
目前的设计实践鼓励上面的#2和#3等功能也提供一个size_t size功能,因此该功能知道可用内存的限制.
char *foo2(char *s, size_t size, const pkg_T *pkg) {
int result = snprintf(s, size, "%02x:%02x:%02x:%02x:%02x:%02x",
pkg->address[0], pkg->address[1], pkg->address[2],
pkg->address[3], pkg->address[4], pkg->address[5]);
// encoding error or not enough room
if (result < 0 || result >= size) return NULL;
return s;
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是分配内存(我赞成以上).这要求调用代码到free()存储器.
#define UINT_MAX_WIDTH (sizeof(unsigned)*CHAR_BIT/3 + 3)
char *foo2alloc(char *s, size_t size, const pkg_T *pkg) {
char buf[(UINT_MAX_WIDTH+3)*6 + 1];
int result = snprintf(buf, sizeof buf, "%02x:%02x:%02x:%02x:%02x:%02x",
pkg->address[0], pkg->address[1], pkg->address[2],
pkg->address[3], pkg->address[4], pkg->address[5]);
// encoding error or not enough room
if (result < 0 || result >= size) return NULL;
return strdup(buf);
}
Run Code Online (Sandbox Code Playgroud)