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