2016-08-29 14 views
1

Das Problem ist folgendes: ich eine dynamische Matrix erstellt, Zeiger mit auf Zeiger matrix1Kopieren eines Zeigers eines Zeigers (Matrix) Werte in C

Ich möchte eine Kopie dieser Matrix in eine andere zu schaffen, matrix2

ich tun möchte, dass so kann ich mess with matrix2 ohne mit matrix1 messing also habe ich versucht, die folgendes zu tun:

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 
} 

Allerdings ist die Programmunterbrechungen und zeigen: Error

Ich verstehe, dass es durch die Art und Weise zu betrachten, wäre es einfacher, die Funktion create_matrix zweimal zu verwenden, für matrix1 und eine andere für matrix2. Aber so wie mein ursprüngliches Programm ist, wäre das zu viel Arbeit, da ich eine Menge Sachen mache, um die Matrix zu machen. Oh, und übrigens, ich möchte vermeiden, C++ zu benutzen, gibt es einen Weg, es zu tun, ohne es zu benutzen? Es wäre besser für mich.

der Code 'create_matrix' ist die folgende:

//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; 
} 
+0

http://StackOverflow.com/Questions/12675800/How-to-copy-matrix-in-c – parik

+2

Sie veröffentlichen nicht den vollständigen Code. –

+0

@parik, das ist keine gültige dup. Der Datentyp ist 'T [N] [M]', während hier 'T ** 'steht. Wenn Sie eine Lösung von dort blind anwenden, wird das Programm wahrscheinlich zum Absturz gebracht. – StoryTeller

Antwort

1

matrix1 Punkte auf dem Feld von Zeilenzeiger, *matrix1 ist ein Zeiger auf ein Feld des ersten Halte Zeile der tatsächlichen Daten und **matrix1 ist der Wert des ersten Elements der ersten Zeile. matrix1 und jedes seiner Elemente sind alle dynamisch zugewiesenen Arrays.

matrix2 ist ein nicht initialisierter (Papierkorb) Zeiger in dem Code, den Sie angezeigt haben. Es hat weder den Zeilenzeiger noch Datenpuffer zugewiesen.

Um Ihr gewünschtes Ergebnis zu erreichen, müssen Sie zunächst die Elemente matrix2 zuordnen und dann nur den Datenanteil von matrix1 kopieren.

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); 

Eine Alternative wäre, einen einzelnen Puffer für die Kopie zuzuweisen. Während dies möglicherweise ein besserer Weg Matrizen im allgemeinen zu speichern, kann es nicht als nützlich für Sie sein, weil Sie nicht in der Lage sein werden, die Erinnerung an matrix2 die gleiche Art und Weise zu befreien, die Sie für matrix1 tun:

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; 
} 
+0

Ich glaube ** Matrix1 ist der Wert des ersten Elements, nicht die Adresse davon. – Brad

+0

@Brad Ich glaube, dass Sie richtig sind. Aktualisiert. –

+0

Als nächstes nehme ich an, dass Ihr memcpy annimmt, dass an der Speicherstelle * matrix1 size1 * size2 int Werte gespeichert sind. Ich denke nicht, dass das der Fall ist. Ich denke, dass dort nur size2 Int-Werte gespeichert sind. Ich denke, das Memcpy liest außerhalb der Grenzen. Sind Sie einverstanden? – Brad

1

Wie Kampf this-

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]; 
    } 
} 
+0

Upvote zum Anschauen, dass der Puffer nicht monolithisch war, lange bevor OP vollständigen Code veröffentlichte. –

-1

Sie Sie müssen den Unterschied zwischen dem Kopieren von Zeigern, dem Erstellen von flachen Kopien und dem Erstellen tiefer Kopien verstehen. Betrachten Sie diese

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

Es gibt nun drei Möglichkeiten, das Kopieren eines Mitarbeiters

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. 

Zeiger Kopie

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

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

Shallow Kopie

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 
} 

Komplette Kopie

Wie Sie sehen können, ist selbst für eine einfache Struktur mit nur einem Feld mit variabler Länge die Erstellung einer tiefen Kopie eine Menge Arbeit. Alle haben ihre Verwendung, obwohl seichte Kopien wahrscheinlich die am wenigsten nützliche und fehleranfälligste der drei sind.

Sie müssen wahrscheinlich nur einen Zeiger zuweisen.

+0

Sie gingen also auf eine Tangente, wo Sie über Strukturen sprechen, die OP nicht verwendet, dann zugegeben, dass Sie nicht wirklich wissen, wie sich das auf die Frage von OP bezieht. Auch deine letzte Antwort ist falsch. –

+0

Ich kann verstehen, was Zeigerkopie ist, aber seichte und tiefe Kopie verwirrt mich. – Hirosam

+0

@ Hirosam. Es ist ein Konzept, das in Sprachen wie Java, wo Zeiger implizit statt explizit sind, viel relevanter ist. Tiefe Kopie bedeutet, dass Sie den Zeiger auf Zeilen und den Inhalt der Zeilen kopieren, während flache Kopie bedeutet, dass Sie nur die Ponter-zu-Zeilen kopieren, aber Ihre Datenpuffer sind die gleichen (das Gegenteil von dem, was Sie wollen). –

Verwandte Themen