字符串的串联和int结果用C赛格故障 [英] Concatenation of string and int results in seg fault in C

查看:113
本文介绍了字符串的串联和int结果用C赛格故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不知道林做错了。我试着用PID创建ID来连接主机名。

 的char * generate_id(无效){
    INT RET;
    焦炭ID [1048];
    焦炭主机名[1024];
    将为pid_t PID = GETPID();
    //主机名[1023] ='\\ 0';    如果((RET =获取主机名(主机名,1024)℃下)){
        PERROR(获取主机名);
        出口(EXIT_FAILURE);
    }
    sprintf的(ID,%s%D,PID);
    的printf(主机名称为%s \\ n,主机名);
    的printf(进程ID为%d \\ n,PID);
    的printf(独有的ID​​是%S,身份证);    返回ID;
}

更新code看到一些答案后

 的char * generate_id(无效){
    INT RET;
    焦炭主机名[1024];
    将为pid_t PID = GETPID();
    //主机名[1023] ='\\ 0';    如果((RET =获取主机名(主机名,1024)℃下)){
        PERROR(获取主机名);
        出口(EXIT_FAILURE);
    }    INT大小=的snprintf(NULL,0,%s%D,主机名,PID);
    字符* ID =的malloc(大小+ 1);    的printf(主机名称为%s \\ n,主机名);
    的printf(进程ID为%d \\ n,PID);
    输出(的唯一ID为%s \\ n,身份证);    返回ID;
}

工作code

 的char * generate_id(无效){
    INT RET;
    焦炭主机名[1024];
    将为pid_t PID = GETPID();
    //主机名[1023] ='\\ 0';    如果((RET =获取主机名(主机名,1024)℃下)){
        PERROR(获取主机名);
        出口(EXIT_FAILURE);
    }    INT大小=的snprintf(NULL,0,%s%D,主机名,PID);
    字符* ID =的malloc(大小+ 1);
    sprintf的(ID,%s%D,主机名,PID);
    的printf(主机名称为%s \\ n,主机名);
    的printf(进程ID为%d \\ n,PID);
    输出(的唯一ID为%s \\ n,身份证);    返回ID;
}


解决方案

问题与格式字符串:

 的sprintf(ID,%s%D,PID);

您格式字符串有两个格式化(%S 对于字符串和%d个 INT ),但只传递一个将为pid_t 。您可能意味着:

 的sprintf(ID,%s%D,主机名,PID);

 的sprintf(ID,%D,PID);

在您的code时,%S 间$ P $点的 PID 作为一个指针。试图取消引用该字符串格式化会导致段错误,因为它是一个无效的指针值。

问题与你的内存管理:

但后来也有未定义行为在code:你声明 ID 是一个堆栈分配数组,但你返回该数组(衰变为这里的指针)。这也是错误的,并可能导致崩溃以后

您需要修改 ID 来堆分配的数组是这样的:

 的char * ID =的malloc(1024);

generate_id 函数的调用者则需要免费的内存时,它的完成。

这可能是一个好主意,只分配所需的空间。您可以使用的snprintf 对于像这样的:

  //确定多少空间字符串的需求。
INT大小=的snprintf(NULL,0,%D,PID);
//分配所需的空间加上NULL终止。
字符* ID =的malloc(大小+ 1);
//其实打印字符串。
sprintf的(ID,%D,PID);

Not sure what Im doing wrong. Im trying to concatenate hostname with pid to create 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;
}

Updated Code After Seeing Some Answers

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;
}

Working Code

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;
}

解决方案

Issue with your format string:

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

Your format string has two formatters (%s for a string and %d for an int), yet you only pass an pid_t. You likely mean:

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

or

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

In your code, the %s interprets the pid as a pointer. Trying to dereference that to format the string causes the segmentation fault as it's an invalid pointer value.

Issue with your memory management:

But then there's also undefined behavior in your code: you declare id to be a stack-allocated array but you're returning that array (which decays into a pointer here). This also is wrong and may lead to a crash later on.

You need to change id to a heap-allocated array like this:

char * id = malloc(1024);

The caller of your generate_id function then needs to free the memory when it's done.

It's probably a good idea to only allocate the space you need. You can use snprintf for that like this:

// 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);

这篇关于字符串的串联和int结果用C赛格故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆