c- 增加数组大小并尝试达到后出现分段错误
c- Segmentation fault after increasing array size and try to reach
#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 x 3 矩阵并打印它然后将它增加 3 x 4 并且在尝试到达数组 [2][0] 时,我遇到了分段错误
什么是 problem.I 检查了很多次,但我找不到任何东西
您的二维矩阵由指向一维 int 数组的指针表示。
数组不是连续的二维数组。使用memcpy将旧数组复制到新数组,在函数increase中,是行不通的。
您必须遍历每个指针,然后遍历指针指向的数组。基本上使用两个嵌套循环,就像打印数组时所做的那样。
在函数 increase 中,代码不会释放指针数组指向的数组:
free(array);
只释放指针数组,同时释放指针数组的每个元素。如果您查看数组的分配方式,这是显而易见的:
array=(int**)malloc(sizeof(int*)*(*row));
for(i=0;i<(*row);++i){
array[i]=(int*)malloc(sizeof(int)*(*col));
}
memcpy(temp,array,sizeof(int)*trow*tcol);
错误。
array
不连续 int
.
array
如下
[int*][int*][int*]...
| |
| +-→[int][int][int]...
|
+-→[int][int][int]...
像这样修复
#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;
}
而不是 memcpy
,realloc
可用于增加 array
的大小。检查 realloc 和 malloc 的 return,因为它们可能会失败。
还应检查 scanf 的 return,因为它也可能会失败。
这不是 scanf,而是使用 fgets 进行输入,并在 get_int_range
函数中使用 strtol 解析输入。
使用 realloc 允许组合 take
和 increase
函数。由于 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")] = '[=10=]';//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 != '[=10=]' && !( delim && strchr ( delim, *end))) {// is *end '[=10=]' or is *end in the set of term characters
line[strcspn ( line, "\n")] = '[=10=]';//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;
}
#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 x 3 矩阵并打印它然后将它增加 3 x 4 并且在尝试到达数组 [2][0] 时,我遇到了分段错误 什么是 problem.I 检查了很多次,但我找不到任何东西
您的二维矩阵由指向一维 int 数组的指针表示。
数组不是连续的二维数组。使用memcpy将旧数组复制到新数组,在函数increase中,是行不通的。
您必须遍历每个指针,然后遍历指针指向的数组。基本上使用两个嵌套循环,就像打印数组时所做的那样。
在函数 increase 中,代码不会释放指针数组指向的数组:
free(array);
只释放指针数组,同时释放指针数组的每个元素。如果您查看数组的分配方式,这是显而易见的:
array=(int**)malloc(sizeof(int*)*(*row));
for(i=0;i<(*row);++i){
array[i]=(int*)malloc(sizeof(int)*(*col));
}
memcpy(temp,array,sizeof(int)*trow*tcol);
错误。
array
不连续 int
.
array
如下
[int*][int*][int*]...
| |
| +-→[int][int][int]...
|
+-→[int][int][int]...
像这样修复
#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;
}
而不是 memcpy
,realloc
可用于增加 array
的大小。检查 realloc 和 malloc 的 return,因为它们可能会失败。
还应检查 scanf 的 return,因为它也可能会失败。
这不是 scanf,而是使用 fgets 进行输入,并在 get_int_range
函数中使用 strtol 解析输入。
使用 realloc 允许组合 take
和 increase
函数。由于 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")] = '[=10=]';//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 != '[=10=]' && !( delim && strchr ( delim, *end))) {// is *end '[=10=]' or is *end in the set of term characters
line[strcspn ( line, "\n")] = '[=10=]';//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;
}