字符串和 int 的串联会导致 C 中的分段错误



我不确定我做错了什么。我正在尝试将hostnamepid连接起来以创建id.

char *generate_id(void) {
    int ret;
    char id[1048];
    char hostname[1024];
    pid_t pid = getpid();
    //hostname[1023] = '';
    if ((ret = gethostname(hostname,1024) < 0)) {
        perror("gethostname");
        exit(EXIT_FAILURE);
    }
    sprintf(id, "%s%d", pid);
    printf("hostname is %sn", hostname);
    printf("The process id is %dn", 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] = '';
    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 %sn", hostname);
    printf("The process id is %dn", pid);
    printf("The unique id is %sn", id);
    return id;
}

编辑:

工作代码:

char *generate_id(void) {
    int ret;
    char hostname[1024];
    pid_t pid = getpid();
    //hostname[1023] = '';
    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 %sn", hostname);
    printf("The process id is %dn", pid);
    printf("The unique id is %sn", id);
    return id;
}
格式

字符串的问题:

sprintf(id, "%s%d", pid);

您的格式字符串有两个格式化程序(%s用于字符串,%d用于int),但您只传递一个pid_t。您可能意味着:

sprintf(id, "%s%d", hostname, pid);

sprintf(id, "%d", pid);

在代码中,%spid解释为指针。尝试取消引用以格式化字符串会导致分段错误,因为它是无效的指针值。

内存管理问题:

但是,您的代码中也存在未定义的行为:您将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) 是坏的。

返回 ID 是错误的,因为它返回指向堆栈上值的指针。一旦你回来,堆栈就不再是你的了。

sprintf(id, "%s%d", pid);

您有两个选择器 %s 和 %d,但只有一个参数 (pid)。您需要输入一个字符串和一个整数,而不仅仅是整数。

相关内容

  • 没有找到相关文章

最新更新