#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;
}
First ı am making 2 by 3 matrix and print it then increase it 3 by 4 and when trying to reach array[2][0], I am taking segmentation fault What is the problem.I checked it many times but I could not find anything
Rather than memcpy
, realloc
could be used to increase the size of array
. Check the return of realloc and malloc as they can fail.
The return of scanf should also be checked as it can fail as well.
Instead of scanf, this uses fgets for input and parses the input with strtol in the get_int_range
function.
Using realloc allows the take
and increase
functions to be combined. Since the take
function now has knowledge of the old and new sizes, the operation of the assign
function can also be included.
takeaway
handles freeing the allocated memory.
#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;
}