Перестановка указателей в структуре не дает мне правильного результата - PullRequest
1 голос
/ 30 апреля 2019

У меня есть struct

typedef struct InfoSession {
    TabNodePtr FirstTab;
    TabNodePtr LastTab;
    TabNodePtr CurrTab;
    TabNodePtr AuxTab;
    char *OpeningAddress;
} InfoSession;

это должен быть сеанс браузера, который контролирует все его вкладки. OpeningAddress является адресом по умолчанию при открытии новой вкладки.

Мой main выглядит так:

int main() {
    InfoSessionPtr  MySession1 = NULL, MySession2 = NULL, CurrSession = NULL;
    int option, flag, n;
    char *OpeningAddress == NULL;
    ...
}

Когда я хочу изменить OpeningAddres с помощью этой функции:

void SessionNewOpeningAddress(InfoSessionPtr Session, char *OpeningAddress1) {
    Session->OpeningAddress = OpeningAddress1;
}

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

Например, если я изменю начальный адрес первого сеанса на "AA", добавление нового сеанса после этого сделает OpeningAddress второго сеанса равным NULL, а не "AA" (что что я хочу).

Добавление нового сеанса (-ов):

            if (MySession1 == NULL && MySession2 == NULL) {
                MySession1 = SessionNew(OpeningAddress);
                CurrSession = MySession1;
                printf("\nNew Session (first) created!\n");
                printf("First Session assigned as 'Current' Session\n");
            } else {
                MySession2 = SessionNew(OpeningAddress);
                CurrSession = MySession2;
                printf("\nA Session already exists, created a second one.\n");
                printf("Second Session assigned as 'Current' Session\n");
            }

Изменение начального адреса:

        printf("\nInsert the new Opening Address:\n");
        scanf("%s", OpeningAddress);
        SessionNewOpeningAddress(CurrSession, OpeningAddress);

Кроме того, код, изменяющий сеанс для управления:

            printf("\nPress 1 to manage first Session or 2 to manage second Session:\n");
            scanf("%d", &n);
            getchar();
            if (n == 1){
                CurrSession = MySession1;
                printf("\nManaging first Session\n");
            } else if (n == 2){
                CurrSession = MySession2;
                printf("\nManaging second Session\n");
            }

Спасибо за вашу помощь.

1 Ответ

1 голос
/ 30 апреля 2019

Проблема проста:

  • вызов SessionNewOpeningAddress(CurrSession, OpeningAddress); устанавливает OpeningAddress член CurrSession для указания массива в области видимости вызывающего, который перезаписывается после этого вызова.Действительно, все поля OpeningAddress могут указывать на один и тот же массив в вызывающей функции.
  • Публикация фрагментов кода, как вы это сделали, бесполезна, большая часть контекста отсутствует, и какой-то другой код может вызвать проблему.
  • скрывать указатели за typedefs, как в TabNodePtr, крайне не рекомендуется.Это может привести к путанице в коде как для начинающих, так и для опытных программистов.

Чтобы решить вашу проблему, вы можете сделать копию строки:

#include <string.h>

void SessionNewOpeningAddress(InfoSessionPtr Session, char *OpeningAddress1) {
    Session->OpeningAddress = OpeningAddress1 ? strdup(OpeningAddress1) : NULL;
}

Вам необходимо освободитьпредыдущее значение, если структура была правильно инициализирована, а также освобождает текущий Session->OpeningAddress, когда структура отбрасывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...