2015-07-02 18 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

struct Person { 
     char *forename; 
     char *surname; 
     int age; 
}; 

void change_struct(struct Person *person, char *forename, char *surname, 
       int age); 
void print_struct(struct Person *person); 

int main(void) 
{ 
     struct Person person1; 
     person1.forename = malloc((strlen("Max") + 1) * sizeof(char)); 
     if (!person1.forename) { 
       exit(EXIT_FAILURE); 
     } 
     strcpy(person1.forename, "Max"); 
     person1.surname = malloc((strlen("Mustermann") + 1) * sizeof(char)); 
     if (!person1.surname) { 
       exit(EXIT_FAILURE); 
     } 
     strcpy(person1.surname, "Mustermann"); 
     person1.age = 35; 

     print_struct(&person1); 

     change_struct(&person1, "Hans", "Bauer", 45); 

     print_struct(&person1); 

     free(person1.forename); 
     free(person1.surname); 

     exit(EXIT_SUCCESS); 
} 

void change_struct(struct Person *person, char *forename, char *surname, 
       int age) 
{ 
     person->forename = realloc(person->forename, 
            (strlen(forename) + 1) * sizeof(char)); 
     if (!person->forename) { 
       exit(EXIT_FAILURE); 
     } 
     strcpy(person->forename, forename); 
     person->surname = realloc(person->surname, 
            (strlen(surname) + 1) * sizeof(char)); 
     if (!person->surname) { 
       exit(EXIT_FAILURE); 
     } 
     strcpy(person->surname, surname); 
     person->age = age; 
} 

void print_struct(struct Person *person) 
{ 
     printf("%s\n", person->forename); 
     printf("%s\n", person->surname); 
     printf("%d\n", person->age); 
} 

指定字符串的指針當在struct分配一個字符串的指針是明確的行爲,如果我會做在結構

person1.forename = "Max"; 
person1.surname = "Mustermann"; 

main()最初不是使用malloc()strcpy()

注:(當然,在這個特定的情況下,我需要也改變change_struct()realloc()電話,因爲它是當realloc()接收非malloc()calloc(),或realloc()創建指針未定義行爲)

如果需要動態內存分配,你可以解釋一下爲什麼?

回答

6

只要你不想修改內容,

person1.forename = "Max"; 
person1.surname = "Mustermann"; 

是完全有效的。

在這種情況下,person1.forename將是一個指向字符串文字和任何試圖修改的內容將導致undefined behaviour

這就是說,

  1. print_struct()功能,你不需要一個指針傳遞到結構。
  2. sizeof(char)保證產生1C。用它來乘法(得到malloc()的大小)是多餘的,可以很容易地省略。
+0

好的,我可以虛心地問downvote的原因嗎? –

+0

我不知道,但我現在認爲''C'是一個相當苛刻的標籤。 (不要試圖開始討論。) –

1
person1.forename = "Max"; 
person1.surname = "Mustermann"; 

你正在你的指針指向字符串常量,所以請記串literls是隻讀的。所以一旦你有了上面的初始化,你就不能修改指針指向的字符串,而malloc()和家族函數分配的內存則不是這種情況。

既然你是分配內存明確,你可以用它來閱讀和write.So你在這裏需要動態分配內存,如果你要修改的指針指向

1

"Max"字符串是一個空結束的讀 - 只有在C中的字符串文字;使用const char*指向第一個字符是明確的和慣用的。

你應該改變你的類型結構元素來const char*如果你要來填充它以這樣一種方式的行爲上修改只讀字面是不確定

當然,您可以設置forename & c。指向另一個字符串。

0

這是一個壞方法。在這種情況下,您可能不會在函數change_struct內部應用函數realloc,因爲字符串文字具有靜態存儲持續時間。它們不是動態分配的

該函數是一個通用函數,它可以接受各種參數forenamesurname的參數,而不僅僅是字符串文字。

例如,該功能可以被稱爲像

char name[] = "Hans"; 

change_struct(&person1, name, "Bauer", 45); 

甚至像

if (some_condition) 
{ 
    char name[] = "Hans"; 

    change_struct(&person1, name, "Bauer", 45); 
} 

在這種情況下的name任何改變也將改變指向的字符串數據的對象的構件forename的結構類型。此外,如果數組name將在某些本地範圍中定義,如if語句中的示例所示,那麼該指針甚至是無效的。