2016-12-27 3 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; 
} 

먼저 2x3 행렬을 만들고 인쇄 한 다음 3을 4 씩 늘리고 배열 [2] [0]에 도달하려고 할 때 세분화 오류가 발생했습니다 문제가 무엇입니까? 여러 번 확인했지만 찾을 수 없습니다.c- 배열 크기를 늘린 후 세그먼트 오류가 발생했습니다.

+1

'memcpy (temp, array, sizeof (int) * trow * tcol);'가 잘못되었습니다. 당신은 각 요소를 복사합니다. 또는 각 행의 요소. 또한 당신은'free (array [i]);' – BLUEPIXY

+0

'memcpy (temp, array, sizeof (int) * trow * tcol);을 필요로한다. free (array);'여기에는 2 개의 에러가 있습니다 : array가 가리키는'(sizeof (int *) * row)'바이트 만있는 곳에서. int'temp' 행의 행에 대해 새 메모리를 할당하고 행마다 행을 복사해야합니다. 또한 'array'를 해제해도 단일 행에 할당 된 메모리가 해제되지 않습니다. – Gerhardh

+0

코드에 행렬 (일명 2D 배열)이 없습니다. 'int **'는 행렬이 아니며, 그것을 나타낼 수도 없습니다. 일단 2D 배열을 사용하면 모든 것이 훨씬 쉬워지고 복사가 잘됩니다. – Olaf

답변

0

보다는 memcpy, realloc

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

픽스 array의 크기를 증가 시키는데 사용될 수있다. realloc과 malloc의 반환이 실패 할 수 있는지 확인하십시오.
scanf의 반환 또한 실패 할 수 있으므로 확인해야합니다.
scanf 대신 입력에 fgets를 사용하고 get_int_range 함수에서 strtol로 입력을 구문 분석합니다.
realloc을 사용하면 takeincrease 기능을 결합 할 수 있습니다. take 함수에는 이전 및 새로운 크기에 대한 지식이 있으므로 assign 함수의 연산을 포함 할 수 있습니다.
takeaway은 할당 된 메모리를 해제합니다.

#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

2 차원 행렬은 1 차원 int 배열을 가리키는 포인터로 나타냅니다.

배열은 인접한 2 차원 배열이 아닙니다. memcpy를 사용하여 이전 배열을 새 배열로 복사하면 함수 증가에서 작동하지 않습니다.

각 포인터를 반복 한 다음 포인터가 가리키는 배열을 통해 반복해야합니다. 기본적으로 배열을 인쇄 할 때처럼 두 개의 중첩 루프를 사용하십시오. 기능 코드를 증가


이 여유 배열 포인터의 배열을 가리키는 않습니다 포인터의

free(array); 

만 배열하여, 해제 될 때 무료 또한 배열의 각 요소를해야 포인터의. 배열이 할당되는 방법을 보면 분명합니다.

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);이 잘못되었습니다.
array은 연속되지 않습니다 int입니다.
array은 다음과 같다. 이

#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; 
}