2016-12-27 1 views
0
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<time.h> 

void print(int **array,int row,int col){ 
    int i,j; 
    for(i=0;i<row;++i){ 
     for(j=0;j<col;++j){ 
      printf("%d ",array[i][j]); 
     } 
     printf("\n"); 
    } 

} 
int **take(int *row,int *col){ 
    int i; int **array; 
    printf("Enter the row number for array \n"); 
    scanf("%d",row); 
    printf("Enter the column number for the array \n"); 
    scanf("%d",col); 

    array=(int**)malloc(sizeof(int*)*(*row)); 
    for(i=0;i<(*row);++i){ 
     array[i]=(int*)malloc(sizeof(int)*(*col)); 
    } 
    return array; 
} 
void assign(int **array,int row,int col){ 
    int i,j; 
    srand(time(NULL)); 

    for(i=0;i<row;++i){ 
     for(j=0;j<col;++j){ 
      array[i][j]=rand()%50; 
     } 
    } 
} 
int **increase(int **array,int *row,int *col){ 

int **temp;int trow=*row;int tcol=*col; 
    temp=take(row,col); 
    memcpy(temp,array,sizeof(int)*trow*tcol); 
    free(array); 
    return temp; 

} 


int main(){ 
    int **array=NULL; int row,col; 

    array=take(&row,&col); 

    assign(array,row,col); 

    print(array,row,col); 

    array=increase(array,&row,&col); 
    array[2][0] = 1; 
    free(array); 
    return 0; 
} 

D'abord, je fais 2 par 3 matrice et imprimer augmenter ensuite 3 par 4 et en essayant d'atteindre array [2] [0], je suis prendre le problème de segmentation Quel est le problème? Je l'ai vérifié plusieurs fois mais je n'ai rien trouvéc- Segmentation fault après avoir augmenté la taille du tableau et essayer d'atteindre

+1

'memcpy (temp, tableau, sizeof (int) * trow * tcol);' est faux. vous copiez chaque élément. ou les éléments de chaque rangée. Vous avez également besoin de 'free (array [i]);' – BLUEPIXY

+0

'memcpy (temp, tableau, sizeof (int) * trow * tcol); free (array); 'Cela a 2 erreurs: A l'endroit où les points du tableau ont seulement' (sizeof (int *) * row) 'bytes alloués. Vous devez allouer de la nouvelle mémoire pour les lignes dans la matrice 'temp' et copier ligne par ligne. Libérer 'array' ne libère pas non plus la mémoire allouée aux lignes simples – Gerhardh

+0

Vous n'avez pas de matrice (alias tableau 2D) dans votre code. 'int **' n'est pas une matrice, ni ne peut en représenter une. Une fois que vous utilisez un tableau 2D, tout sera beaucoup plus facile et la copie fonctionnera. – Olaf

Répondre

0

Plutôt que memcpy, realloc pourrait être utilisé pour augmenter la taille de array. Vérifiez le retour de realloc et malloc car ils peuvent échouer.
Le retour de scanf doit également être vérifié car il peut également échouer.
Au lieu de scanf, cela utilise des fgets pour l'entrée et analyse l'entrée avec strtol dans la fonction get_int_range.
L'utilisation de realloc permet de combiner les fonctions take et increase. Depuis la fonction take a maintenant la connaissance des anciennes et nouvelles tailles, le fonctionnement de la fonction assign peut également être inclus.
takeaway gère libérer la mémoire allouée.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <time.h> 
#include <errno.h> 
#include <limits.h> 

//inputs 
// char *line : pointer to text to be parsed 
// char **next : pointer to pointer to allow modification of caller's pointer 
// char *delim : pointer to characters to be considered terminators 
// int *value : pointer to int to allow modification of caller's int 
// int min : minimum value of range 
// int max : maximum value of range 
// returns : 0 failure or 1 success 
int get_int_range (char *line, char **next, char *delim, int *value, int min, int max) 
{ 
    long int input = 0; 
    char *end = NULL;//will point to end of parsed value 

    if (line == NULL) { 
     return 0; 
    } 
    errno = 0; 
    input = strtol (line, &end, 10);//get the integer from the line. end will point to the end of the parsed value 
    if ((errno == ERANGE && (input == LONG_MAX || input == LONG_MIN)) 
    || (errno != 0 && input == 0)){// parsing error from strtol 
     perror ("input"); 
     return 0; 
    } 
    if (end == line) {// nothing was parsed. no digits 
     line[strcspn (line, "\n")] = '\0';//remove newline 
     printf ("input [%s] MUST be a number\n", line); 
     return 0;// return failure 
    } 
    // *end is the character that end points to 
    if (*end != '\0' && !(delim && strchr (delim, *end))) {// is *end '\0' or is *end in the set of term characters 
     line[strcspn (line, "\n")] = '\0';//remove newline 
     printf ("problem with input: [%s] \n", line); 
     return 0; 
    } 
    if (input < min || input > max) {// parsed value is outside of range 
     printf ("input out of range %d to %d\n", min, max); 
     return 0; 
    } 

    if (next != NULL) {// if next is NULL, caller did not want pointer to end of parsed value 
     *next = end;// *next allows modification to caller's pointer 
    } 
    if (value == NULL) { 
     return 0; 
    } 
    *value = input;// *value allows modification to callers int 
    return 1;// success 
} 

void print(int **array,int row,int col){ 
    int i,j; 

    for(i=0;i<row;++i){ 
     for(j=0;j<col;++j){ 
      printf("%d ",array[i][j]); 
     } 
     printf("\n"); 
    } 
} 

int **take(int **array, int *row, int *col){ 
    char line[256] = ""; 
    int i; 
    int each = 0; 
    int newrow = 0; 
    int newcol = 0; 
    int valid = 0; 
    int **temp = 0; 
    int *temprow = 0; 

    do { 
     printf("Enter the row number for array \n"); 
     fgets (line, sizeof (line), stdin);//read a line 
     valid = get_int_range (line, NULL, "\n", &newrow, (*row) + 1, INT_MAX);// call to parse a value 
    } while (!valid); 
    do { 
     printf("Enter the column number for the array \n"); 
     fgets (line, sizeof (line), stdin);//read a line 
     valid = get_int_range (line, NULL, "\n", &newcol, (*col) + 1, INT_MAX);// call to parse a value 
    } while (!valid); 

    if ((temp = realloc (array, sizeof(int*) * (newrow))) == NULL) { 
     fprintf (stderr, "problem reallocating\n"); 
     return array; 
    } 
    array = temp; 

    for(i=0;i<(*row);++i){//realloc existing rows 
     if ((temprow = realloc (array[i], sizeof (int) * (newcol))) == NULL) { 
      fprintf (stderr, "problem reallocating row \n"); 
      return array; 
     } 
     array[i] = temprow; 
     for (each = *col; each < newcol; each++) { 
      array[i][each] = rand () % 50; 
     } 
    } 
    for(i=(*row);i<newrow;++i){// malloc new rows 
     if ((array[i] = malloc (sizeof (int) * (newcol))) == NULL) { 
      fprintf (stderr, "problem allocating row \n"); 
      return array; 
     } 
     for (each = 0; each < newcol; each++) { 
      array[i][each] = rand () % 50; 
     } 
    } 
    *row = newrow; 
    *col = newcol; 
    return array; 
} 

int **takeaway (int **array, int *row, int *col) {//free allocated memory 
    *col = 0; 
    while (*row){ 
     *row -= 1; 
     free (array[*row]); 
    } 
    free (array); 
    return NULL; 
} 

int main(){ 
    int **array=NULL;//so realloc will work on the first call 
    int row = 0; 
    int col = 0; 

    srand(time(NULL));//call srand once early in the program 

    array=take(array,&row,&col); 
    print(array,row,col); 
    array=take(array,&row,&col); 
    array[2][0] = 1; 
    print(array,row,col); 
    array = takeaway (array, &row, &col); 
    return 0; 
} 
1

Votre matrice bidimensionnelle est représentée par des pointeurs qui pointent vers des tableaux intimensionnels int.

Le tableau n'est pas un tableau bidimensionnel contigu. L'utilisation de memcpy pour copier l'ancien tableau vers le nouveau, dans l'augmentation de la fonction, ne fonctionnera pas.

Vous devrez parcourir chaque pointeur, puis traverser le tableau vers lequel pointe le pointeur. Fondamentalement, utilisez deux boucles imbriquées, tout comme vous le faites lorsque vous imprimez les tableaux.


Dans la fonction augmenter le code ne tableaux pas libre le tableau de pointeur pointe vers:

free(array); 

Seuls les tableaux de pointeurs est libéré, quand il devrait également gratuit chaque élément du tableau de pointeurs. Cela est évident si vous regardez comment le tableau est alloué:

array=(int**)malloc(sizeof(int*)*(*row)); 
for(i=0;i<(*row);++i){ 
    array[i]=(int*)malloc(sizeof(int)*(*col)); 
} 
1

memcpy(temp,array,sizeof(int)*trow*tcol); est faux.
array n'est pas continue int.
array est comme suit.

[int*][int*][int*]... 
 |   | 
 |   +-→[int][int][int]... 
 | 
 +-→[int][int][int]... 

fix comme ce

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

void print(int **array, int row, int col){ 
    int i, j; 
    for(i = 0; i < row; ++i){ 
     for(j = 0; j < col; ++j){ 
      printf("%2d ", array[i][j]); 
     } 
     printf("\n"); 
    } 
} 

int **take(int *row,int *col){ 
    int **array, i; 
    printf("Enter the row number for array \n"); 
    scanf("%d", row); 
    printf("Enter the column number for the array \n"); 
    scanf("%d", col); 

    array = malloc(sizeof(int*) * (*row)); 
    for(i = 0; i < (*row); ++i){ 
     array[i] = calloc(*col, sizeof(int)); 
    } 
    return array; 
} 

void assign(int **array,int row,int col){ 
    int i,j; 
    srand(time(NULL)); 

    for(i=0;i<row;++i){ 
     for(j=0;j<col;++j){ 
      array[i][j]=rand()%50; 
     } 
    } 
} 
int **increase(int **array, int *row, int *col){ 
    int **temp, trow = *row, tcol = *col; 

    temp=take(row, col); 
    if(*row < trow || *col < tcol){ 
     printf("Was decreased.\n"); 
     for(int i = 0; i < *row; ++i) 
      free(temp[i]); 
     free(temp); 
     *row = trow; *col = tcol; 
     return array;//not change 
    } 
    for(int i = 0; i < trow; ++i){ 
     memcpy(temp[i], array[i], sizeof(int) * tcol); 
     free(array[i]); 
    } 
    free(array); 
    return temp; 
} 

int main(void){ 
    int **array = NULL; 
    int row, col; 

    array=take(&row, &col); 
    assign(array, row, col); 
    print(array, row, col); 

    array = increase(array, &row, &col); 
    //test: 2, 3 --> 3, 4 
    array[2][0] = 1; 
    print(array, row, col); 

    for(int i = 0; i < row; ++i) 
     free(array[i]); 
    free(array); 

    return 0; 
}