2016-04-26 4 views
-1

Ich bin mir nicht sicher, was ich falsch mache. Ich versuche, hostname mit pid zu verknüpfen, um id zu erstellen.Verkettung von String und int ergibt Segmentierungsfehler in C

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

EDIT:

aktualisiert Code nach ein paar Antworten zu lesen:

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

EDIT:

Arbeitscode:

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

sprintf '% s% d', und dann nur' pid' bereitstellen? Sie haben zwei Formatierungszeichen, also müssen Sie zwei Werte angeben. –

+0

Warum haben Sie '% s% d' in sprintf sollte das nicht nur'% d' sein – JackVanier

+1

Sie sollten 'pid_t pid' bei der Lieferung als' int' darstellen Streit. 'sprintf (id,"% d ", (int) pid);' –

Antwort

3

Problem mit dem Format-String:

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

Ihr Format-String hat zwei Formatierer (%s für einen String und %d für ein int), doch nur ein pid_t passieren. Du meinst wahrscheinlich:

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

oder

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

In Ihrem Code, der %s die pid als Zeiger interpretiert. Der Versuch, die Formatierung der Zeichenfolge zu dereferenzieren, verursacht den Segmentierungsfehler, da es sich um einen ungültigen Zeigerwert handelt.

Problem mit Ihrer Speicherverwaltung:

Aber dann gibt es auch undefiniertes Verhalten in Ihrem Code: Sie erklären id ein Stapel zugeordnete Array sein, aber Sie Rückkehr das Array (die in einen Zeiger zerfällt hier). Dies ist auch falsch und kann später zu einem Absturz führen.

Sie müssen wie diese id zu einem Haufen zugeordnete Array ändern:

char * id = malloc(1024); 

Der Anrufer Ihrer generate_id Funktion muss dann den Speicher free, wenn es fertig ist.

Es ist wahrscheinlich eine gute Idee, nur den benötigten Speicherplatz zuzuweisen. Sie können snprintf dafür wie folgt verwenden:

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

Danke für die Hilfe, habe ich den Code in der Frage aktualisiert, wenn ich versuche, die eindeutige ID zu drucken, aber leer. –

+0

Das liegt daran, dass Sie nur den Speicherplatz _allocate_, aber Sie verpassen den eigentlichen Aufruf von 'sprintf'. Zuerst wird "snprintf" auf besondere Weise aufgerufen (beachten Sie das zusätzliche 'n' im Namen) (' NULL' und '0' als die ersten beiden Argumente). Auf diese Weise messen Sie die Größe. Dann müssen Sie den Platz mit "malloc" zuweisen, und dann müssen Sie wirklich mit 'sprintf' in diesen Raum drucken. – DarkDust

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

Sie haben zwei Selektoren% s und% d, aber nur einen Parameter (pid). Sie müssen eine Zeichenfolge und eine Ganzzahl statt nur der Ganzzahl eingeben.

1

nicht sicher, wo Sie sind Speicherzugriffsfehler, aber Sie haben ein paar Probleme.

snprintf() ist viel sicherer und wird den Puffer id [] nicht überschreiben. sprintf könnte den Puffer überlaufen

sprintf (id, "% s% d", pid) ist schlecht wie oben erwähnt.

Rückgabe-ID ist schlecht, da es den Zeiger auf einen Wert auf dem Stapel zurückgibt. Sobald du zurückkommst, gehört der Stapel dir nicht mehr.

+0

Wie gibt man dann richtig einen String zurück? –

+0

Sie müssen entweder den Speicher zuordnen (malloc) und den Anrufer freigeben lassen oder einen statischen Puffer verwenden, von dem der Anrufer weiß, dass er kopiert oder verwendet werden muss, bevor diese Routine oder ähnliche Methoden erneut aufgerufen werden. – Russ