2011-03-21 14 views
32

Jeśli chcę replikować struktury w innym (w C), jakie są pro & con od:Przypisanie struktury lub memcpy?

struct1 = struct2; 

vs

memcpy(&struct1, &struct2, sizeof(mystruct_t)); 

są one równoważne? Czy jest różnica w wydajności lub wykorzystaniu pamięci?

+3

Uważaj tylko na przydzielanie pamięci wewnątrz struktury. Na przykład, jeśli masz strukturę zawierającą wskaźnik do łańcucha i alokujesz pamięć dla ciągu znaków. Ta pamięć nie zostanie skopiowana. wskaźnik do pamięci zostaje skopiowany, ale nie sama pamięć. Innymi słowy, ten typ zadania nie jest głęboką kopią. Nie jest też memem waniliowym dla tej materii. Może być mylące, kto jest właścicielem przydzielonej pamięci. – Pemdas

+0

Myślę, że to pytanie jest bardziej odpowiednie dla Stackoverflow. – karlphillip

+2

Myślę, że to pytanie zostało już dobrze odebrane tutaj: http://stackoverflow.com/q/4931123/176769 – karlphillip

Odpowiedz

31

Notacja struct1=struct2; jest nie tylko bardziej zwięzła, ale także krótsza i pozostawia więcej możliwości optymalizacji kompilatorowi. Semantyczne znaczenie = jest zadaniem, podczas gdy memcpy po prostu kopiuje pamięć. To także duża różnica w czytelności, chociaż w tym przypadku robi się to samo w przypadku memcpy.

Użyj =.

+0

Główny problem na s = mystruct między struct s i struct * s. Oba działają ładnie z równymi, więc nie można zobaczyć różnicy poprzez czytanie. * s daje ci identyczne, podczas gdy struct s daje ci kopię. Kiedy przychodzi czas na zwolnienie (alokację), działa to dobrze z identycznymi strukturami; ale przecieka tajemnicą, jeśli głupio zrobisz tylko jeden dealloc z wersją struct. Szybsza jest również praca ze wskaźnikami. Po prostu trzymaj się tego, co robisz, a wtedy wszystko powinno być w porządku. YMMV. – DragonLord

2

Nie jestem pewien różnicy wydajności, chociaż domyślam się, że większość kompilatorów używałaby memcpy pod maską.

Wolałbym zlecenie w większości przypadków, jest o wiele łatwiejsze do odczytania i jest dużo bardziej jednoznaczny co do celu. Wyobraź sobie, że zmieniłeś typ jednej ze struktur, kompilator poprowadzi cię do zmian, które były potrzebne, albo dając błąd kompilatora, albo używając operatora = (jeśli taki istnieje). Natomiast drugi ślepo wykonałby kopię z możliwością wywołania subtelnego błędu.

2

Nie ma nieodłącznego powodu, dla którego jeden byłby lepszy w działaniu niż drugi. Różne kompilatory i ich wersje mogą się różnić, więc jeśli naprawdę zależy Ci na tym, profilujesz i porównujesz i używasz faktów jako podstawy do podjęcia decyzji.

Proste przypisanie jest bardziej czytelne.

Przypisanie jest nieco bardziej ryzykowne, aby uzyskać błąd, więc przypisujesz wskaźniki do struktur, a nie do wskazanych struktur. Jeśli się tego obawiacie, dopilnujecie, aby wasze testy jednostkowe obejmowały to. Nie dbałbym o to ryzyko. (Podobnie memcpy jest ryzykowne, bo można dostać rozmiar struct złego.)

+0

Nie ma nic ryzykownego w 'memcpy' jeśli używasz' sizeof' i poprawnej struktury. Przypuszczam, że można uzyskać błąd struktury i nie byłoby błędu.Sądzę jednak, że prawdopodobnie w końcu dostaniesz błąd segmentacji. –

4

Sprawdź to rozmowy o tym samym temacie: http://bytes.com/topic/c/answers/670947-struct-assignment

Zasadniczo istnieje wiele sporów o przypadkach narożnych w tym wątku o tym, co zrobi strukturalna kopia. Jest całkiem jasne, czy wszyscy członkowie struktury są prostymi wartościami (int, double itd.). Zamieszanie przychodzi z tym, co dzieje się z tablicami i wskaźnikami oraz bajtami dopełnienia.

Wszystko powinno być całkiem jasne, co dzieje się z memcpy, ponieważ jest to dosłowna kopia każdego bajtu. Obejmuje to zarówno bezwzględne wskaźniki pamięci, przesunięcia względne itp.