Это код, который я тестирую для копирования структуры.
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 (new, string) в строке 40, то выбрасывает Ошибка шины: 10.
Я ожидал, что значение Изменено а также оригинал совпадают в строке 41 и 42. Но это не будет работать. В чем проблема назначения?
Я знал, что ошибка шины: 10 произошла из-за недостатка места назначения. Но мой название поле в структуре является указателем (в строке 5). Если я изменил имя поля, как
char name[100];
Работает нормально и Изменено а также оригинал значения разные! Хотя я назначил это как указатель.
В чем проблема присвоения этой структуры?
temp.name — указатель на символ
После копии temp = *(people+5);
, temp.name указывает на байты, содержащие «Найджел».
Пока проблем нет. Но вы не можете использовать этот указатель в качестве вывода для strcpy (); strcpy попытается перезаписать его, и он будет храниться в постоянной памяти.
Вы можете сделать это:
temp.name = «Ahn»;
… поскольку все, что вы здесь делаете, это изменение указателя (temp.name), чтобы он указывал на другую область памяти, которая заранее настроена для содержания «Ahn».
Это на самом деле не имеет ничего общего со структурным копированием.
У вас будет такая же проблема, если вы попытаетесь сделать strcpy(people[3].name, "Ahn")
Когда вы объявили запись базы данных, все имена (Фред, Джим, Фред …) были помещены в read-only
память сегмента данных и тому name
указатель символов указывает на их начальные адреса.
Когда вы делаете strcpy(temp.name, "Ahn");
, вы пытаетесь писать только для чтения. Пытаюсь написать в read-only
память вызовет ошибку шины.
Решением было бы выделить память для name
а затем сделать strcpy
, Также хорошей практикой программирования является использование strncpy
вместо strcpy