Правилен начин два указателя да сочат към една и съща част от паметта

Имам структура:

struct generic_attribute{
    int current_value;
    int previous_value;
};

И конструктор, който извежда указател към тази структура:

struct generic_attribute* construct_generic_attribute(int current_value){
    struct generic_attribute *ga_ptr;
    ga_ptr = malloc (sizeof (struct generic_attribute));
    ga_ptr->current_value = current_value;
    ga_ptr->previous_value = 0;
    return ga_ptr;
}

Сега, в друга функция, искам да дефинирам указател и да го настроя да сочи към същия адрес като указателя, който извежда горният конструктор.

struct tagged_attribute* construct_tagged_attribute(int num_args, int *args){
    ...
    struct generic_attribute* generic = malloc (sizeof(struct generic_attribute));
    generic = construct_generic_attribute(args[0]);
    ...
}

Изглежда, че това, което правя тук, е следното:

1) Дефинирам указател „generic“ и разпределям част от паметта, за да задържа екземпляр на структура generic_attribute.

2) Извиквам функция construct_generic_attribute, в рамките на която програмата отново разпределя част от паметта с размер на структура generic_attribute. Той извежда указател към тази част от паметта.

3) В construct_tagged_attribute зададох "генеричен" указател, равен на изхода на указателя от функцията construct_generic_attribute, така че сега и двата сочат към един и същ слот за памет.

Изглежда обаче, че разпределям два пъти повече памет, отколкото трябва да разпределя.

Има ли начин да разпределя памет само веднъж, без да получавам грешка при сегментиране, защото не успях да разпределя място за "генеричен" указател? Като алтернатива, погрешно ли разбирам какво се случва в този код?


person RebeccaK375    schedule 28.06.2015    source източник


Отговори (3)


struct generic_attribute* generic = construct_generic_attribute(args[0]);

Трябва да свърши работа. Променливата показалец е точно това, променлива. Можете да обменяте стойности на указателя точно като числа.

person Will Hartung    schedule 28.06.2015

  1. Да, разбирате погрешно, но не мога да разбера какво мислите, че се случва, за да обясня защо не е наред.

  2. struct generic_attribute *generic = construct_generic_attribute(args[0]); указателят е вид стойност. Ако присвоите указател на друг, получавате два указателя към едно и също нещо, без никакво разпределение на паметта. Тъй като C не управлява паметта вместо вас, от вас зависи да се уверите, че всеки обект, който е разпределен, е освободен точно веднъж и че не се опитвате да използвате указатели към обект, след като е бил освободен.

person hobbs    schedule 28.06.2015

Тук

    struct generic_attribute* generic = malloc (sizeof(struct generic_attribute));

разпределяте блок памет, достатъчно голям, за да запазите generic_attribute структура, след което съхранявате указател към тази структура (технически: адрес на блока) в променливата generic. Забележка: не инициализирате членовете на структурата.

След това в

    generic = construct_generic_attribute(args[0]);

извиквате функция, която вътрешно разпределя (друг) блок памет и го инициализира и връща указател към него (който е бил съхранен в променлива ga_ptr по време на изпълнение на функцията). След това върнатият указател се присвоява на променливата generic, като презаписва стойността, съхранена там от предишна инструкция. Следователно вие губите достъп до първата разпределена структура.

РЕДАКТИРАНЕ

Страхувам се, че не разбирам напълно какво се опитвате да постигнете. Ако искате два указателя към една и съща структура, просто declarega1 и му присвоете указател към създадената структура:

    struct generic_attribute *ga1 = construct_generic_attribute(args[0]);

след това направете копие на показалеца:

    struct generic_attribute *ga2 = ga1;
person CiaPan    schedule 28.06.2015