2016-10-09 15 views
5

Myślałem Czytałem gdzieś, że przy stosowaniu wskaźników i chcemy skopiować zawartość jednego do drugiego, że istnieją dwie opcje:skopiować zawartość jeden wskaźnik do innego

  • wykorzystujące memcpy lub
  • tylko przypisywanie ich za pomocą =?

Jednak w dolnej przykład Właśnie testowałem to przez przydzielanie pamięci dla dwóch wskaźników, a następnie przypisanie drugi, zmieniając first..but następnie wejście mojego drugiego wskaźnika zmienia się także .. Co robię źle : /.

typedef struct { 

    int a; 
    int b; 
    int c; 
} my_struct; 


int main(int argc, char** argv) { 

    my_struct* first = malloc(sizeof(my_struct)); 
    first->a = 100; first->b = 101; first->c = 1000; 

    my_struct* bb = malloc(sizeof(my_struct)); 

    printf("first %d %d %d\n", first->a, first->b, first->c); 
    bb = first; 
    printf("second %d %d %d\n", bb->a, first->b, bb->c); 


    first->a = 55; first->b = 55; first->c = 89; 
    printf("second %d %d %d\n", bb->a, first->b, bb->c); 
} 
+1

@MDXF: Nie rozumiem, w jaki sposób 'strdup()' jest zdalnie istotne. Gdyby można było głosować w dół, głosowałbym nad propozycją. –

Odpowiedz

7

Moment zrobić bb = first;, bb i first są skierowane do tej samej lokalizacji pamięci. first->a = 55; first->b = 55; first->c = 89; zmieni wartości dla a, b i c w tej lokalizacji. Oryginalna wartość first nadal pozostaje w pamięci, ale nie ma już do niej dostępu.

Myślę, że możesz chcieć zrobić to *bb = *first;.

+0

OK, dziękuję bardzo za wyjaśnienie, to sprawiło, że było to trochę jaśniejsze .. Ale jaka jest konwencja w C o robieniu kopiowania treści, jest częstsza lub bardziej powszechna. zadanie, które napisałeś? – malajedala

+0

Nie sądzę, że istnieje konwencja _per se_. To naprawdę zależy od scenariusza, ponieważ kopiowanie danych zawierających wskaźniki jest dość zaawansowanym tematem, IMO. – Anzurio

2

Twoja wiedza o memcpy jest poprawna, ale nie można przypisać zawartość „położenie wskazywane przez wskaźniki” po prostu poprzez przypisanie wskaźników jak to zrobiłeś w swoim oświadczeniu, o którym mowa powyżej.

Jesteś przypisanie jednego wskaźnika do drugiego w następującym stwierdzeniem:

bb = first; 

Teraz oba te punkt w tej samej lokalizacji pamięci (myśleć bb jako alias do first).

Jeśli chcesz skopiować dane następnie kopiowania przy użyciu „dane wskazywane przez wskaźniki*bb = *first

+0

Ok, więc nie ma sposobu na używanie memcpy w tych przypadkach? – malajedala

+1

@malajedala '* bb = * first;' – potrzebie

1

Jak już wspomniano, jeśli masz wskaźnik first wskazujący do jakiegoś miejsca w pamięci i dokonać przyporządkowania bb = first, gdzie bb jest kompatybilny typ wskaźnika, a następnie bb wskazuje tym samym adresem co first. To nie kopiuje zawartości pamięci przywoływanej przez first do lokalizacji pierwotnie wskazanej przez bb. Kopiuje wartość wskaźnika, który jest adresem, do bb.

Jeśli zdefiniujesz tablicę A, nie możesz wykonać przypisania B = A, aby skopiować zawartość A do B. Musisz użyć strcpy() lub memcpy() lub jakiejś takiej funkcji. Ale struktury są różne. Możesz przypisać zawartość jednej struktury do kompatybilnej struktury.

W przykładzie bb i first są wskaźniki do kodowanym, a kiedy piszesz bb = first, teraz oba wskaźniki odwoływać się do tego samego adresu w pamięci, a nie masz już dostępu do pamięci pierwotnie wskazanej przez bb - więc teraz mieć wyciek pamięci!Ale *bb isą strukturami, a gdy napiszesz *bb = *first, zawartość struct *first zostanie skopiowana do struktury *bb. Więc teraz masz dwie różne struktury, w różnych miejscach w pamięci, każda z kopiami tych samych trzech s. int.

Jeśli typ my_struct zawierał wskaźnik do int, a następnie po cesji *bb = *first oni każdy zawiera kopię wskaźnik do tego samego miejsca w pamięci, ale danymi wskazywanymi przez te wskaźniki nie będą kopiowane. Tak więc, jeśli struktura zawierała wskaźnik do tablicy, skopiowany zostałby tylko wskaźnik, a nie zawartość tablicy, która byłaby współdzielona przez dwie struktury.

Powiązane problemy