Поменять 2 элемента в массиве указателей (на строки разной длины) в C - PullRequest
0 голосов
/ 08 февраля 2019

Я пытаюсь поменять 2 элемента в массиве указателей, и эти указатели указывают на строки различной длины.Другая функция, занимающаяся выделением памяти для массива и строк, функция swap просто возьмет массив char ** и поменяет местами элементы, которые мне нужно поменять местами.Что меня интересует, так это когда я меняю указатели, выделяется ли выделенная память для каждой строки, когда я меняюсь, или это портится?

Это не мой точный код из моего проекта, но что он делаетидентичен:

int main() {

    char** array = malloc(10 * sizeof(char*));
    char* a = (char*)malloc(4*sizeof(char*));
    char* b = (char*)malloc(14*sizeof(char*));

    a = "test";
    b = "this is a test";

    array[0] = a;
    array[1] = b;

    char*temp;
    temp = array[0];
    array[0] = array[1];
    array[1] = temp;


    free[array];
    free[a];
    free[b];

    return 0;

}

Слишком резюмируя, мой вопрос касается выделенной памяти a и b.Распределенная память по-прежнему корректна / исправна после замены?

1 Ответ

0 голосов
/ 08 февраля 2019

Своп в порядке.Проблема в том, как вы выделяете память для указателей a и b и как вы назначаете им строки.И нет, когда вы используете алгоритм подкачки, блоки памяти не будут зашифрованы.Если вы не измените a и b, то все будет в порядке (что вы делаете ).В C все работает так:

char *a = malloc(4 * sizeof(char));
a = "test"; // this is an error, and you will lose the memory block

Это выделяет 4 единицы памяти, каждая единица имеет размер char.Когда вы делаете:

char *a = malloc(4 * sizeof(char**));

Это выделяет 4 единицы памяти, каждая единица имеет размер char * или указатель на char.Это не то, что вы хотели.Кроме того, если вы хотите поместить строку в pointer to char, вам следует использовать функцию strncpy (или strndup, если она доступна).

char *a = malloc(5 * sizeof(char)); // always alloc space for the NULL byte
strncpy(a, "test", 4);

char *b = strndup("test", 4); 

free(a);
free(b);

Обратите внимание, что вы выделили память длямассив указателей в правильном направлении, выполнив:

char **array = malloc(10 * sizeof(char*));

... даст вам блок из 10 единиц памяти, каждый из которых имеет размер char *.Затем вы можете обратиться к каждой из этих единиц памяти, указав указатель array.

Пара указателей (без каламбура): во-первых, вам не нужно приводить к возвращению malloc.Во-вторых, вам не нужно умножать на sizeof(char).Ниже приведена небольшая рабочая версия кода.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
    char **array = malloc(10 * sizeof(char*));
    char *a = malloc(5);
    char *b = malloc(15);

    strcpy(a, "test");
    strcpy(b, "this is a test");

    char *temp;

    array[0] = a;
    array[1] = b;

    // prints "test" then "this is a test"
    printf("%s\n%s\n\n", array[0], array[1]);

    // this swaps them
    temp = array[0];
    array[0] = array[1];
    array[1] = temp;

    // now it prints "this is a test" and "test"
    printf("%s\n%s\n\n", array[0], array[1]);

    free(a);
    free(b);
    free(array);
}
...