Memory allocation question

This is a discussion on Memory allocation question within the C Programming forums, part of the General Programming Boards category; I think my program is crapping out because of faulty memory allocation. I want my code to read matrix.dat and ...

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    24

    Memory allocation question

    I think my program is crapping out because of faulty memory allocation.

    I want my code to read matrix.dat and store the numbers in a 4x4 matrix using pointer ........... Then I would like to print the matrix line by line but instead of the correct numbers, I get a long string of random numbers.

    This is my overall code:
    Code:
    void prob2(void)
    {
    FILE *Inf_1;
    double **A=0, *b=0;
    int row=0;
    char text[81];
    int k=0,t=0;
    
    b = (double *)malloc((size_t)32);
    A = (double **)calloc(16, sizeof(double *));
    
    
    Inf_1 = fopen("matrix.dat", "r");
    printf(" Put your solution for problem 2 here:\n");
    //By using a pointer to pointer **A and the function calloc()
    //allocate the memory for the 4x4 matrix A[][]
    //By using a pointer *b and the function malloc() allocate the memory
    //for the 4-dimensional vector b[]
    
    if(b==NULL)
    {
    printf("(main) malloc failed in double *b\n");
    exit(1);
    }
    if(A==NULL)
    {
    printf("(main) calloc failed in double **a\n");
    exit(2); 
    }
    for(row=0;row<16;row++)
    {
    A[row] = (double *)calloc(16, sizeof(double *));
    if(A[row]==NULL)
    {
    printf("(main) calloc failed in double *A[]\n");
    exit(4);
    }
    }
    
    //Read the components of A and b from the given input file matrix.dat.
    //The last line of the input file contains the components of b. The rows of
    //matrix A are the first four lines of the input file.
    
    
    
    if ((Inf_1 == NULL))
    {
    printf("Error opening the file\n");
    exit(1);
    }
    
    while(fgets(text,81,Inf_1)!=NULL)
    {
    
    if (k < 5) {
       sscanf(text, "%lf %lf %lf %lf", &A[t][0], &A[t][1], &A[t][2], &A[t][3]);
    k++;
    t++;
    
       }
    
    else
    sscanf(text, "%lf %lf %lf %lf", b, b+1, b+2, b+3);
    }
    
    
    //Print the components of A[][] row by row, and the components of b[].
    printf("\n");
    for (k=0;k<4;k++) {
    printf("a[%d][] = %lf %lf %lf %lf\n",k+1,&A[k][0],&A[k][1],&A[k][2],&A[k][3]);
    }
    
    }
    I'm trying to isolate my problem and I would like others to check over some key components.

    1. True or false: This block of code reads file matrix.dat line by line (there are 5 lines total; every line has five numbers) and stores the numbers in a 4x4 matrix in A.

    The else statement reads the last line on matrix.dat and stores the 4 numbers using pointer b.

    Code:
    while(fgets(text,81,Inf_1)!=NULL)
    {
    
    if (k < 5) {
       sscanf(text, "%lf %lf %lf %lf", &A[t][0], &A[t][1], &A[t][2], &A[t][3]);
    k++;
    t++;
    
       }
    
    else
    sscanf(text, "%lf %lf %lf %lf", b, b+1, b+2, b+3);
    }
    2. True/false: This loop of 16 allocates some memory for each row in my 4x4 matrix.
    Code:
    for(row=0;row<16;row++)
    {
    A[row] = (double *)calloc(16, sizeof(double *));
    if(A[row]==NULL)
    {
    printf("(main) calloc failed in double *A[]\n");
    exit(4);
    }
    }
    3. True/false: This prints the numbers on matrix.dat.
    Code:
    for (k=0;k<4;k++) {
    printf("a[%d][] = %lf %lf %lf %lf\n",k+1,&A[k][0],&A[k][1],&A[k][2],&A[k][3]);
    }
    This is matrix.dat by the way:
    Code:
    -1.0 1.0 -4.0 -0.5
     2.0 1.5  3.0  2.1
    -3.1 0.7 -2.5  4.2
     1.4 0.3  2.4 -1.9
     0.0 1.2 -3.0 -0.5
    Anyone know why my output is:
    a[1][] = 0.000000 0.000000 -51371471092907161178215517680210201070883690439141 41531451094331347592107749648920245017535748877081 62688667630716613389078816118684482410273456360890 67293804625029028204093572680075524848238599093026 66019186939209269159188445012222149148388435131742 64331967577566243348855100186528081647614005590664 15104.000000 0.000000
    a[2][] = 0.000000 0.000000 -51371471092907161178215517680210201070883690439141 41531451094331347592107749648920245017535748877081 62688667630716613389078816118684482410273456360890 67293804625029028204093572680075524848238599093026 66019186939209269159188445012222149148388435131742 64331967577566243348855100186528081647614005590664 15104.000000 0.000000
    a[3][] = 0.000000 0.000000 -51371471092907161178215517680210201070883690439141 41531451094331347592107749648920245017535748877081 62688667630716613389078816118684482410273456360890 67293804625029028204093572680075524848238599093026 66019186939209269159188445012222149148388435131742 64331967577566243348855100186528081647614005590664 15104.000000 0.000000
    a[4][] = 0.000000 0.000000 -51371471092907161178215517680210201070883690439141 41531451094331347592107749648920245017535748877081 62688667630716613389078816118684482410273456360890 67293804625029028204093572680075524848238599093026 66019186939209269159188445012222149148388435131742 64331967577566243348855100186528081647614005590664 15104.000000 0.000000

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    I would say 1 and 3 are true and 2 is false.

    You're going to have to decide whether A is 4x4 or 16x16, or some mixture. Currently it's 16x?, depending on the size difference between double and double* (each row does not have enough room to store 16 doubles, it has enough room for 16 double*'s, despite the fact that you don't intend to store double* in it; it's probably enough room for 8 doubles, but the indexing is going to be way wrong).

  3. #3
    Registered User
    Join Date
    Oct 2008
    Posts
    24
    I'm trying to make my matrix a 4x4 matrix. What's the indication that it's a 16x16 matrix?

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by dakarn View Post
    I'm trying to make my matrix a 4x4 matrix. What's the indication that it's a 16x16 matrix?
    The bunches of "16" in the code, and no "4"s.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Posts
    24
    I switched up my code a little bit but my understanding may be faulty here:

    A = (double **)calloc(16, sizeof(double *));
    Allocates enough memory for 16 doubles?
    Code:
    for(row=0;row<4;row++)
    {
    A[row] = (double *)calloc(4, sizeof(double *));
    if(A[row]==NULL)
    {
    printf("(main) calloc failed in double *A[]\n");
    exit(4);
    }
    }
    allocates memory for 4 doubles for each row of 4?

    Thanks for the replies tabstop!

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by dakarn View Post
    I switched up my code a little bit but my understanding may be faulty here:

    A = (double **)calloc(16, sizeof(double *));
    Allocates enough memory for 16 doubles?
    No, it allocates 16 rows (that don't yet have any memory in it).
    Code:
    for(row=0;row<4;row++) { A[row] = (double *)calloc(4, sizeof(double *)); if(A[row]==NULL) { printf("(main) calloc failed in double *A[]\n"); exit(4); } }
    allocates memory for 4 doubles for each row of 4?

    Thanks for the replies tabstop!
    It allocates memory for four pointers-to-double, not four doubles. (This may be enough memory, but is not guaranteed to be.)

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,904
    Warning 3 warning C6272: Non-float passed as argument '3' when float is required in call to 'printf' g:\w00t\visual studio 2008\projects\temp\temp4.cpp 72
    Warning 4 warning C6272: Non-float passed as argument '4' when float is required in call to 'printf' g:\w00t\visual studio 2008\projects\temp\temp4.cpp 72
    Warning 5 warning C6272: Non-float passed as argument '5' when float is required in call to 'printf' g:\w00t\visual studio 2008\projects\temp\temp4.cpp 72
    Warning 6 warning C6272: Non-float passed as argument '6' when float is required in call to 'printf' g:\w00t\visual studio 2008\projects\temp\temp4.cpp 72

    Code:
    	for (k=0;k<4;k++) {
    		printf("a[&#37;d][] = %lf %lf %lf %lf\n",k+1,&A[k][0],&A[k][1],&A[k][2],&A[k][3]);
    	}
    Perhaps you had better fix them?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    24
    Great catch Elysia!

    This may be a stupid question but what kind of value is it if not a float?

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,904
    You are passing double*, not double, to printf.
    Besides, it should be &#37;f, not %lf.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Oct 2008
    Posts
    24
    Yay fixed using:
    Code:
    for (k=0;k<4;k++) {
    printf("a[&#37;d][] = %f %f %f %f\n",k+1,*A[k],*A[k]+1,*A[k]+2,*A[k]+3);
    }
    My problem now is that it prints values but it prints the wrong values:

    This is what it should print:
    Code:
    -1.0 1.0 -4.0 -0.5
     2.0 1.5  3.0  2.1
    -3.1 0.7 -2.5  4.2
     1.4 0.3  2.4 -1.9
    This is what it prints instead:
    Code:
    a[1][] = -1.000000 0.000000 1.000000 2.000000
    a[2][] = 2.000000 3.000000 4.000000 5.000000
    a[3][] = -3.100000 -2.100000 -1.100000 -0.100000
    a[4][] = 1.400000 2.400000 3.400000 4.400000
    Wtf? where did 4.4 come from?

    To eliminate some ways it can possibly be wrong, I removed the sscanf section and just explicitly stated matrix A.
    Here is my code now:


    Code:
    void prob2(void)
    {
    FILE *Inf_1;
    double **A, *b;
    int row=0;
    char text[81];
    int k=0,t=0,l=0;
    
    b = (double *)malloc((size_t)32);
    A = (double **)calloc(4, sizeof(double *));
    
    
    Inf_1 = fopen("matrix.dat", "r");
    printf(" Put your solution for problem 2 here:\n");
    //By using a pointer to pointer **A and the function calloc()
    //allocate the memory for the 4x4 matrix A[][]
    //By using a pointer *b and the function malloc() allocate the memory
    //for the 4-dimensional vector b[]
    
    if(b==NULL)
    {
    printf("(main) malloc failed in double *b\n");
    exit(1);
    }
    if(A==NULL)
    {
    printf("(main) calloc failed in double **a\n");
    exit(2); 
    }
    
    for(row=0;row<4;row++)
    {
    A[row] = (double *)calloc(4, sizeof(double));
    if(A[row]==NULL)
    {
    printf("(main) calloc failed in double *A[]\n");
    exit(4);
    }
    }
    
    //Read the components of A and b from the given input file matrix.dat.
    //The last line of the input file contains the components of b. The rows of
    //matrix A are the first four lines of the input file.
    
    
    
    if ((Inf_1 == NULL))
    {
    printf("Error opening the file\n");
    exit(1);
    }
    
    
    A[0][0]=-1.0;A[0][1]= 1.0;A[0][2]= -4.0;A[0][3]= -0.5;
    A[1][0]= 2.0;A[1][1]= 1.5;A[1][2]=  3.0;A[1][3]=  2.1;
    A[2][0]=-3.1;A[2][1]= 0.7;A[2][2]= -2.5;A[2][3]=  4.2;
    A[3][0]= 1.4;A[3][1]= 0.3;A[3][2]=  2.4;A[3][3]= -1.9;
    
    
    //Print the components of A[][] row by row, and the components of b[].
    printf("\n");
    for (l=0;l<4;l++) {
    printf("a[%d][] = %f %f %f %f\n",l+1,*A[l],*A[l]+1,*A[l]+2,*A[l]+3);
    }
    }
    Anyone know why my program is printing the wrong values?

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Do you have anything against using A[l][0] instead of *A[l]?

    The problem stems from precedence of the operators:
    you are actually doing
    Code:
    *A[l], (*A[l])+1.0, (*A[l])+2.0, (*A[l])+3.0
    rather than:
    Code:
    *A[l], *(A[l]+1), *(A[l])+2), *(A[l]+3)
    Oh, and don't use variables called "l" - it is very hard to see the difference between lower-case L and the number 1.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,755
    You should have a go at fixing your indentation, it's non-existent!.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Static Memory allocation
    By p3rry in forum C Programming
    Replies: 25
    Last Post: 12-23-2008, 08:30 AM
  2. A question related to dynamic memory allocation
    By spiit231 in forum C Programming
    Replies: 2
    Last Post: 03-11-2008, 01:25 AM
  3. Memory allocation and deallocation
    By Micko in forum C++ Programming
    Replies: 3
    Last Post: 08-19-2005, 07:45 PM
  4. Memory Allocation :: C/C++
    By kuphryn in forum C++ Programming
    Replies: 4
    Last Post: 08-15-2002, 11:38 AM
  5. Dynamic Memory Allocation for fstream (binary)
    By kuphryn in forum C++ Programming
    Replies: 2
    Last Post: 12-12-2001, 10:52 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21