Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
217 views
in Technique[技术] by (71.8m points)

Concatenation of string and int results in segmentation fault in C

I am not sure what I'm doing wrong. I'm 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] = '';

    if ((ret = gethostname(hostname,1024) < 0)) {
        perror("gethostname");
        exit(EXIT_FAILURE);
    }
    sprintf(id, "%s%d", pid);
    printf("hostname is %s
", hostname);
    printf("The process id is %d
", pid);
    printf("The unique id is %s", id);

    return id;
}

EDIT:

Updated code after reading some answers:

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 %s
", hostname);
    printf("The process id is %d
", pid);
    printf("The unique id is %s
", id);

    return id;
}

EDIT:

Working code:

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 %s
", hostname);
    printf("The process id is %d
", pid);
    printf("The unique id is %s
", id);

    return id;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...