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

最初に2行3列の行列を作成し、それを3行ずつ増やして配列[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つのエラーがあります:配列が'(sizeof(int *)* row) 'バイトしか割り当てられていない場所で。あなたは 'temp'行列の行に新しいメモリを割り当て、行ごとにコピーする必要があります。また、 'array'を解放しても、単一行に割り当てられたメモリは解放されません。 – Gerhardh

+0

コード内に行列(別名2D配列)がありません。 'int **'は行列ではなく、それを表すこともできません。一度2D配列を使用すると、すべてがはるかに簡単になり、コピーが機能します。 – Olaf

答えて

0

むしろよりmemcpyreallocよう

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

修正がarrayのサイズを大きくするために使用することができます。 reallocとmallocの復帰が失敗することを確認してください。
scanfの復帰も失敗する可能性があるので、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を使用して古い配列を新しい配列にコピーすると、関数の増加で機能しません。

各ポインタを繰り返した後、ポインタが指している配列を通過する必要があります。配列を印刷するときと同じように、基本的に2つのネストされたループを使用します。機能において


コードは、ポインタ配列が指すフリーアレイない増加:

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; 
} 
関連する問題