Копирование указателя значения указателя (матрицы) в C

Проблема заключается в следующем: я создал динамическую матрицу, используя указатель на указатель matrix1

Я хочу создать копию этой матрицы в другую, matrix2

Я хочу сделать это, чтобы я мог связываться с matrix2 не возиться с matrix1Поэтому я попытался сделать следующее:

int main()
{
    int **matrix1, **matrix2, size1 = 10, size2 = 2;
    matrix1 = create_matrix(size1, size2);

    //I want to copy the value of matrix1 into matrixq2 and NOT the index
    **matrix2 = **matrix1
}

Однако программа ломается и показывает следующее: ошибка

Я понимаю, что, как это выглядит, было бы проще использовать функцию create_matrix два раза, для matrix1 и еще один для matrix2, Но то, что моя оригинальная программа - это слишком много работы, так как я делаю много вещей, чтобы сделать матрицу. Да, и, кстати, я хочу избежать использования C++, есть ли способ сделать это без его использования? Это было бы лучше для меня.

код 'create_matrix' выглядит следующим образом:

//The program will read a file with the name of endereco, and create a matrix contPx3 out of it
int ** cria_matrix(char endereco[], int contP)
{
    FILE *fPointer;
    int i, contE, auxIndex, auxNum, **processos, cont_line = 0;
    char line[100];
    bool flag = true, flag2;

    fPointer = fopen(endereco, "r");

//Here the creation of the matrix
    processos = (int**)malloc(sizeof(int*) * contP);
    for (i = 0; i < contP; i++)
        processos[i] = malloc(sizeof(int) * 3);



//For now and on, is the rules of how the data will be placed on the matrix
    contP = 0;
    while (!feof(fPointer) && flag)
    {

        memset(&line[0], 'Ì', sizeof(line));
        fgets(line, 100 , fPointer);
//Bassicaly is that in each line there will be 3 numbers only, diveded but as many spaces you want. The numbeer will be placed on the matrix on the determined line they are.
        auxIndex = 0;
        flag2 = false;
        if(line[0] != '#')
            for (i = 0; i < 100; i++)
            {
                if (line[i] != ' ' && line[i] != '\n' && line[i] != '\0' && line[i] != 'Ì')//&&  line[i] != 'à'
                {
                    auxNum = line[i] - '0';
                    processos[contP][auxIndex] = auxNum;
                    auxIndex++;
                    flag2 = true;

                }
            }

        if (flag2)
            contP++;



        cont_line++;
        if (auxIndex != 3 && auxIndex != 0)
        {
            flag = false;
            printf("ERRO na linha: %d No processo: %d\nProvavelmente mais ou menos que 3 numeros separado por espacos\n", cont_line, contP);
        }

    }
    fclose(fPointer);
    if (!flag)
        system("PAUSE");
    return processos;
}

3 ответа

Решение

matrix1 указывает на массив указателей строк, *matrix1 является указателем на массив, содержащий первую строку фактических данных, и **matrix1 это значение первого элемента первого ряда. matrix1 и каждый из его элементов - это динамически распределяемые массивы.

matrix2 является неинициализированным (мусорным) указателем в коде, который вы отобразили. Он не имеет ни указателя строки, ни выделенных буферов данных.

Чтобы достичь желаемого результата, нужно сначала выделить элементы matrix2затем скопируйте только часть данных matrix1 над.

int **copy_matrix(int **mat, int size1, int size1)
{
    int row;

    int **res = malloc(size1 * sizeof(int *));
    for(row = 0; row < size1; row++) {
        res[row] = malloc(size2 * sizeof(int));
        memcpy(res[row], mat[row], size2 * sizeof(int));
    }
    return res;
}

...

matrix2 = copy_matrix(matrix1, size1, size2);

Альтернативой может быть выделение одного буфера для копии. Хотя это, возможно, лучший способ хранения матриц в целом, он может оказаться не столь полезным для вас, поскольку вы не сможете освободить память о matrix2 так же, как вы делаете для matrix1:

int **copy_matrix(int **mat, int size1, int size2)
{
    int row;
    int **res = malloc(size1 * sizeof(int *));
    res[0] = malloc(size1 * size2 * sizeof(int));

    for(row = 0; row < size1; row++) {
        res[row] = res[0] + row * size2;
        memcpy(res[row], mat[row], size2 * sizeof(int));
    }
    return res;
}

Как насчет этого-

matrix2 = (int**)malloc(sizeof(int*)*size1);
for(int idx = 0; idx < size1; ++idx) {
    matrix2[idx] = (int*)malloc(sizeof(int)*size2);
    for(int idx2 = 0; idx2 < size2; ++idx2) {
        matrix2[idx][idx2] = matrix1[idx][idx2];
    }
}

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

struct employee
{
   char *name;
   float salary;
   int payrollid;
}

Теперь есть три способа копирования сотрудника

struct employee * emp1;  // points to an employee, set up somehow
struct employee * emp2;  // empty pointer, null or whatever

emp2 = emp1;  // copy pointers. emp1 and emp2 now point to the same object.

Копия указателя

struct employee  employee1;  // employee, set up
struct employee  employee2;  // uninitalised emplyee

memcpy(&employee2, &employee1, sizeof(struct employee)); // shallow copy

Мелкая копия

struct employee * emp1;  // points to an employee, set up somehow
struct employee * emp2;  // empty pointer, null or whatever

emp2 = copyemployee(emp1);

struct employee *copyemployee(struct employee *e)
{
   struct employee *answer = malloc(sizeof(struct employee));
   if(!answer)
     goto error_exit;
   answer->name = malloc(strlen(e->name) + 1);
   if(!answer->name)
      goto error_exit;
   strcpy(answer>name, e->name);
   answer->salary = e->salary;
   answer->payroolid = e->payrollid;
   return answer;
error_exit:
   /* out of memory handle somehow, usually by returning null
}

Глубокая копия

Как видите, даже для простой структуры с одним полем переменной длины создание глубокой копии - это довольно трудоемкий процесс. У всех есть их использование, хотя мелкие копии, вероятно, наименее полезны и наиболее подвержены ошибкам из трех.

Вам просто нужно назначить указатель, вероятно.

Другие вопросы по тегам