Замена структур по значению (массив указателей) - PullRequest
1 голос
/ 26 мая 2020

У меня есть эта структура (двусвязный список с информацией, представленной в виде массива из 37 указателей):

typedef struct list {
    struct list* next;
    struct list* prev;
    char *arr[37];
} List;

И я должен поменять местами любые два элемента. Я пробовал поменять их местами по указателям, но не смог найти решения (так что, если вы можете мне с этим помочь, я буду рад). Итак, я придумал решение, которого опасался с самого начала:

void swap_values(List *p1, List *p2) {
    char **temparr = malloc(37 * sizeof(char*));
    for (int i = 0; i < 37; i++) {
        *(temparr + i) = malloc(sizeof(p1 -> arr[i]));
        strcpy(temparr[i], p1 -> arr[i]);
    }
    for (int i = 0; i < 37; i++) {
        strcpy(p1 -> arr[i], p2 -> arr[i]);
    }
    for (int i = 0; i < 37; i++) {
        strcpy(p2 -> arr[i], temparr[i]);
        free(*(temparr + i));
    }
    free(temparr);
}

Это правильный способ обмена их содержимым? Это не кажется правильным. Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 26 мая 2020

Вопрос не совсем ясен, но я предполагаю, что ваша функция получает указатели на два элемента, которые являются членами списков (может или не может быть одним и тем же списком), и вы хотите, чтобы один занял место другого в своем списке и наоборот наоборот.

Если да, то вы можете скопировать arr с помощью memcpy (поскольку массивы не могут быть присвоены по значению) и оставить указатели связывания нетронутыми:

void swap_values(List *p1, List *p2) 
{
    List temp  = *p1;
    memcpy(&p1->arr, &p2->arr, sizeof p1->arr);
    memcpy(&p2->arr, &temp.arr, sizeof p2->arr);
}
0 голосов
/ 26 мая 2020

Это правильный способ замены их содержимого?

Если вы хотите поменять местами часть данных (и оставить указатели next / prev нетронутыми), вам нужно:

void swap_values(List *p1, List *p2) 
{
    char* tmp;
    for (int i = 0; i < 37; i++) 
    {
        tmp = p1->arr[i];
        p1->arr[i] = p2->arr[i];
        p2->arr[i] = tmp;
    } 
}

Альтернативный подход:

void swap_values(List *p1, List *p2) 
{
    char *tmp[37];
    memcpy(tmp, p1->arr, 37 * sizeof(char*));
    memcpy(p1->arr, p2->arr, 37 * sizeof(char*));
    memcpy(p2->arr, tmp, 37 * sizeof(char*));
}

Если вы хотите поменять местами узлы (вместо данных внутри), вам понадобится другой прототип функции. Это связано с тем, что заменяемые узлы могут быть первым и / или последним узлами. В этом случае указатели head и / или tail изменятся.

Возможно что-то вроде:

void swap_values(List *p1, List *p2, List **head, List **tail){ ... }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...