Home > Software engineering >  Calloc Error: unable to allocate, not enough space
Calloc Error: unable to allocate, not enough space

Time:07-29

  // Read input
#include <stdio.h>
int** mat = NULL;
int read()
{
    int n = 101;
    const int MAXLINE = 4 * 101;
    char* line = (char*)malloc(MAXLINE * sizeof(char));

    if (!line)
    {
        perror("Unable to allocate space for line");
        free(line);
        exit(1);
    }

    int rowCount = 0;
    while (rowCount < n && fgets(line, MAXLINE, stdin))
    {
        char* token = (char*)malloc(MAXLINE * sizeof(char));
        if (!token)
        {
            perror("Unable to allocate space for token");
            free(token);
            exit(1);
        }
        token = strtok(line, " ");

        // initialize mat
        if (rowCount == 0)
        {
            char* ptr = NULL;
            n = strtol(token, ptr, 10);
            //printf("%d", n);

            if (n < 1 || n > 100)
            {
                perror("Invalid Input, n is out of range");
                free(token);
                exit(1);
            }
            mat = (int**)malloc(n * sizeof(int*));
            if (!mat)
            {
                perror("Unable to allocate space for mat");
                free(mat);
                exit(1);
            }
            for (int i = 0; i < n; i  )
            {
                mat[i] = (int*)calloc(n * sizeof(int));
                if (!mat[i])
                {
                    perror("Unable to allocate space for mat[i]");
                    free(mat[i]);
                    exit(1);
                }
            }
        }
        else // fill mat
        {
            int colCount = 0;
            while (token)
            {
                if (rowCount == colCount)
                {
                    mat[rowCount][colCount] = 0;
                }
                else if (!strcmp("x", token) || !strcmp("x\n", token))
                {
                    mat[rowCount][colCount] = -1;
                    mat[colCount][rowCount] = -1;
                }
                else
                {
                    char* ptr = NULL;
                    int time = strtol(token, ptr, 10);
                    mat[rowCount][colCount] = time;
                    mat[colCount][rowCount] = time;
                }
                token = strtok(NULL, " ");
                colCount  ;
            }
        }
        rowCount  ;
        //free(token);
    }

    return n;
}

This read function will read a input matrix from stdin and store it in mat. a 5 by 5 matrix input is like the following:

5
1
1 1
1 1 1
1 1 1 1

Sometime I get the error msg: Unable to allocate space for mat[i], not enough space. But most of the time the function works with the same input. I am not very good at C, please help. Thank you in advance.

update: I added: printf("Unable to allocate space for mat[%d]", i); it says unable to allocate space for mat[4].

CodePudding user response:

  1. Turn up your compiler's warnings (e.g. -Wall with gcc or clang).
  2. Your compiler will complain that it doesn't know about all of the functions you're using. Add all headers required:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
  3. Now that those headers are there, your compiler will complain that:
    <source>:54:32: error: too few arguments to function 'calloc'
       54 |                 mat[i] = (int*)calloc(n * sizeof(int));
          |                                ^~~~~~
    /usr/include/stdlib.h:542:14: note: declared here
      542 | extern void *calloc (size_t __nmemb, size_t __size) 
    
  4. Fix the calloc() invocation to be correct; above, you'll see it should be "number of members, size of each member":
    mat[i] = (int*)calloc(n, sizeof(int));
    

You had been calling calloc with a single argument, so it read another off the stack, and were you unlucky enough, that value on the stack might have been, say, 3735928559, which might be a bit too much to allocate, especially multiplied with the other value you passed in.

You'll also see you've been calling strtol() with an invalid second argument; it should be char**, not char*. Happily, you can just replace that with an inline NULL:

n = strtol(token, NULL, 10);
  • Related