0

I want to store numbers with double precision,but it is printing garbage values. I tried changing malloc to calloc, even then I got garbage values. Can anyone explain why this is happening?

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    double **mat1;
    int i,j,k,size;

    printf("Enter the matrix size");
    scanf("%d",&size);

    mat1 = (double**)malloc(size*sizeof(double*));
    for(i=0;i<size;i++)
        mat1[i]=(double*)malloc(size*sizeof(double));

    if(mat1 != NULL) {
        // Enter the input matrix
        printf("\nEnter the elements of matrix\n");
        for(i=0;i<size;i++){
            for(j=0;j<size;j++)
                scanf("%d",&mat1[i][j]);
        }

        //Printing Input Matrix
        printf("\n Entered Matrix 1: \n");
        for(i=0;i<size;i++){
            for(j=0;j<size;j++)
                printf("%d ",mat1[i][j]);
        }
    }
    else {
        printf("error");
    }
}
Schwern
  • 153,029
  • 25
  • 195
  • 336
me333
  • 1
  • 3
  • 10
    you are using wrong specifier for `scanf` and `printf`, `%d` is intended for signed integers, try with `%g` – Jack Feb 04 '17 at 00:13
  • 2
    Also, I hear that casting malloc return values isn't a good idea in C. – synchronizer Feb 04 '17 at 00:19
  • 4
    [don't cast malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar Feb 04 '17 at 00:24
  • 2
    Your code has relevant warnings, but warnings have to be turned on. Usually this is done with `-Wall`. Recompile with warnings, fix them, and see if you still have a problem. – Schwern Feb 04 '17 at 00:26
  • Checking `if(mat1 != NULL)` at that point is already too late since you already tried accessing `mat1[i]` in the previous cycle. Also, don't cast the result of `malloc`. Finally, piling up all variable declarations at the beginning of the function is not a good practice. – AnT stands with Russia Feb 04 '17 at 00:29
  • I agree with @Jack's identification of the problem. I suggest using `%lf` as your solution. http://stackoverflow.com/questions/210590/why-does-scanf-need-lf-for-doubles-when-printf-is-okay-with-just-f – Jonathan Chiang Feb 04 '17 at 02:24

1 Answers1

1

In addition to the comments, there are a couple of issues related to validation that will bite you if you fail to check. Primarily you are faced with two such issues in your code (that are applicable every time you do it).

(1) Always validate EVERY allocation. As @AnT noted, checking if(mat1 != NULL) is already too late. You must check each allocation. e.g.

/* allocate & VALIDATE */
if (!(mat1 = malloc (size * sizeof *mat1))) {
    fprintf (stderr, "error: virtual memory exhausted.\n");
    return 1;
}

and

for (i = 0; i < size; i++)  /* allocate & VALIDATE */
    if (!(mat1[i] = malloc (size * sizeof **mat1))) {
        fprintf (stderr, "error: virtual memory exhausted.\n");
        return 1;
    }

(2) Always validate ALL user input. (for all you know there is a cat stepping on the keyboard). It too is a simple task:

/* Enter the input matrix */
printf ("\nEnter the elements of matrix\n");
for (i = 0; i < size; i++) {
    for (j = 0; j < size; j++)
        if (scanf ("%lf", &mat1[i][j]) != 1) {  /* VALIDATE */
            fprintf (stderr, "error: invalid conversion.\n");
            return 1;
        }
}

If you follow those two rules, your debugging time will be greatly reduced. (not to mention your code will be robust).

If you allocate memory, do not forget to free it. While sure, in this small snippet of code, the memory is freed on exit. But when you start writing functions that allocate memory, if you are not already in the habit of tracking and freeing your allocations, you are just asking for trouble.

Lastly, you can always throw a putchar ('\n') into your print loop to tidy things up. e.g.

/* Printing Input Matrix */
printf ("\n Entered Matrix 1: \n");
for (i = 0; i < size; i++) {
    for (j = 0; j < size; j++)
        printf (" %6.2lf", mat1[i][j]);
    putchar ('\n');
}

Example Use/Output

$ ./bin/matrixdbg
Enter the matrix size: 2

Enter the elements of matrix
1.1
2.2
3.3
4.4

 Entered Matrix 1:
   1.10   2.20
   3.30   4.40

Good luck with your coding. Let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Thanks for the detailed explanation. – me333 Aug 13 '19 at 19:37
  • Glad it helped. You can also use `perror` in place of `fprintf` to report allocation failure errors and `errno` will be set. (e.g. `if (!(mat1 = malloc (size * sizeof *mat1))) { perror ("malloc-mat1"); ...` The key is to ***validate*** EVERY allocation just as you ***validate*** EVERY user-input `:)` – David C. Rankin Aug 13 '19 at 20:07