Ошибка шины в структуре C

Это код, который я тестирую для копирования структуры.

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

Работает нормально и Изменено а также оригинал значения разные! Хотя я назначил это как указатель.

В чем проблема присвоения этой структуры?

6

Решение

temp.name — указатель на символ
После копии temp = *(people+5);, temp.name указывает на байты, содержащие «Найджел».

Пока проблем нет. Но вы не можете использовать этот указатель в качестве вывода для strcpy (); strcpy попытается перезаписать его, и он будет храниться в постоянной памяти.

Вы можете сделать это:

temp.name = «Ahn»;

… поскольку все, что вы здесь делаете, это изменение указателя (temp.name), чтобы он указывал на другую область памяти, которая заранее настроена для содержания «Ahn».

Это на самом деле не имеет ничего общего со структурным копированием.
У вас будет такая же проблема, если вы попытаетесь сделать strcpy(people[3].name, "Ahn")

3

Другие решения

Когда вы объявили запись базы данных, все имена (Фред, Джим, Фред …) были помещены в read-only память сегмента данных и тому name указатель символов указывает на их начальные адреса.

Когда вы делаете strcpy(temp.name, "Ahn");, вы пытаетесь писать только для чтения. Пытаюсь написать в read-only память вызовет ошибку шины.

Решением было бы выделить память для name а затем сделать strcpy, Также хорошей практикой программирования является использование strncpy вместо strcpy

1