Ваша проблема - неправильное понимание указателей.Давайте начнем с некоторого очень похожего кода, который будет работать.
#include <string.h>
#include <stdio.h>
typedef struct { char name[10]; } Item;
typedef struct { Item item; } MyStruct; // <--- Removed the *
MyStruct make(char *name) {
MyStruct st;
Item item;
strncpy(item.name, name, 10); // <--- strncpy because name[] is a fixed length
st.item = item; // <-- Removed the &; *copies* item into st
printf("name: %s\n", st.item.name); // <-- . rather than ->
return st;
}
int main() {
MyStruct s1, s2;
s1 = make("hi");
s2 = make("hey");
printf("\nname: %s\n", s1.item.name); // <-- . rather than ->
printf("name: %s\n", s2.item.name); // <-- . rather than ->
}
В этом коде я избавился от указателей, и все должно работать.Item
- это 10 символов, а MyStruct
- также 10 символов.Когда вы возвращаете его, эти 10 символов памяти копируются, как int.
Но вы этого не делали;Вы добавили указатели.Поскольку item
является локальной переменной, она находится в текущем кадре стека, а не в куче.Кадр стека исчезает в конце текущей области.(Но это не на самом деле исчезает. Это просто неопределенное поведение, чтобы ссылаться на него из области видимости, поэтому он может возвращать что угодно.)
Выполнение этого без указателей означает больше копирования (хотя на самом деле это не так)это намного больше копирования, в 64-битной системе указатель составляет 8 байт).Это также означает, что изменения в одной копии не влияют на другие.Это либо хорошо, либо плохо в зависимости от вашей проблемы.Избавление от указателей таким способом может быть очень хорошим дизайном, если структура не становится слишком большой.После того, как вы добавите указатели, вам нужно будет управлять памятью и принимать решение о владении, а также о том, когда следует освободить память и все другие головные боли.От вашей проблемы зависит, какой подход лучше.
Как примечание, если вы идете этим путем, нет причин создавать промежуточное звено item
(и это неэффективно, потому что он делает две копиистрока).Вместо этого вы просто скопируете прямо в st
:
MyStruct make(char *name) {
MyStruct st;
strncpy(st.item.name, name, 10);
printf("name: %s\n", st.item.name);
return st;
}