2013-12-18 54 views
6

這是我測試複製結構體的代碼。C中的總線錯誤struct

1 #include <stdio.h> 
2 #include <string.h> 
3 
4 typedef struct emp_struct { 
5  char *name; 
6  int employee_no; 
7  float salary, 
8   tax_to_date; 
9 } Employee; 
10 
11 typedef Employee Database[10]; 
12 
13 Database people = { 
14  {"Fred", 10, 10000, 3000}, 
15  {"Jim", 9, 12000, 3100.5}, 
16  {"Fred", 13, 1000000, 30}, 
17  {"Mary", 11, 170000, 4000}, 
18  {"Judith", 45, 130000, 50000}, 
19  {"Nigel", 10, 5000, 1200}, 
20  {"Trevor", 10, 20000, 6000}, 
21  {"Karen", 10, 120000, 34000}, 
22  {"Marianne", 10, 50000, 12000}, 
23  {"Mildred", 10, 100000, 30000} 
24 }; 
25 
26 int main() { 
27  // array act like pointer, thus pointing + pointing = ERROR 
28  printf("people[1]->name: ERROR\n"); 
29  // jump its memory amount of struct size 
30  printf("(people+1)->name:%s\n",(people+1)->name); 
31  // array works as a pointer 
32  printf("people[3].name:%s\n",people[3].name); 
33 
34  /* Is it possible to assign struct to struct? */ 
35  printf("\nAssigning struct to struct\n"); 
36  Employee temp; 
37  temp = *(people+5); // Nigel Record 
38  printf("Name: %s\n",temp.name); 
39  // exchange 
40  strcpy(temp.name, "Ahn"); 
41  printf("Changed: %s\n",temp.name); 
42  printf("Original: %s\n",people[5].name); 
43 
44  return 0; 
45 } 

當我試圖的strcpy(新的,字符串)在管線40,然後將其拋出總線錯誤:10

我預計值改變是線41和42相同,但它不會工作。什麼是分配問題?

我知道總線錯誤:10是由於缺乏賦值空間而發生的。但我的名稱字段在結構中是指針(在第5行)。如果我改變名稱字段一樣

char name[100]; 

它工作正常和改變原始值是不同的!即使我將它指定爲指針。

這個結構賦值的問題是什麼?

+5

你永遠不會爲'temp.name'分配內存,並且數據庫中的值指向應該被視爲常量的數據。如果您嘗試寫入該區域,可能會發生任何事情;你的操作系統顯然只是選擇了觸發一個SIGBUS。 – cHao

+0

@cHao。我已經嘗試temp->名稱像指針分配,但它拋出了引用錯誤。然後,以'malloc'的方式分配* name字段是有道理的。 – Sogo

+1

@cHao我試着用'char * name =(char *)malloc(sizeof(char)* 100);'並且它可以工作。你是對的。我認爲模糊的分配內存總是出現錯誤。謝謝! – Sogo

回答

3

temp.name是一個指向char的指針。 複製temp = *(people+5);後,temp.name指向包含「Nigel」的字節。

到目前爲止,沒有問題。但是你不能使用該指針作爲strcpy()的輸出。 strcpy會嘗試覆蓋它,並將其存儲在只讀存儲器中。

您可以做到這一點:

temp.name =「Ahn」;

...因爲你在這裏所做的只是改變指針(temp.name)以指向預先設置的包含「Ahn」的不同內存區域。

這實際上與結構化複製無關。 您將有同樣的問題,如果你嘗試做strcpy(people[3].name, "Ahn")

1

當你聲明的數據庫記錄,所有的名字(弗雷德,吉姆,弗雷德......)被放置在read-only存儲器中的數據段和name字符指針指向它們的起始地址。

當您做strcpy(temp.name, "Ahn");時,您正嘗試以只讀方式寫入。試圖寫入read-only內存將導致總線錯誤。

解決方法是爲name分配內存,然後執行strcpy。另外一個好的編程習慣是使用strncpy而不是strcpy