string和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; }
格式字符串问题:
sprintf(id, "%s%d", pid);
您的格式字符串有两个格式化程序(字符串为%s
, int
为%d
),但您只传递了一个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);
不知道你在哪里segfaulting但你有一些问题。
snprintf()更安全,不会溢出id []缓冲区。 sprintf可能会超出缓冲区
sprintf(id,“%s%d”,pid)如上所述是坏的。
返回id是坏的,因为它返回指向堆栈上的值的指针。 一旦你返回,堆栈就不再是你的了。
sprintf(id, "%s%d", pid);
您有两个选择器%s和%d,但只有一个参数(pid)。 你需要输入一个字符串和一个整数而不是整数。