0

I'm trying to obtain a char * matrix in C language, but runtime errors occurred to me. The following code shows how I've tried to do this. Can anyone tell me where I'm wrong and why? I'm new in C programming, but I came from Java's and PHP's worlds. Thanks in advance for your interesting and help

int rows = 10;
int cols = 3;

//I create rows
char *** result = calloc(rows, sizeof(char **));

//I create cols
for (int i = 0; i < cols; i++)
{
    result[i] = calloc(cols, sizeof(char *));
}

//Load values into the matrix
for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < cols; j++)
    {
        result[i][j] = (char *)malloc(100 * sizeof(char));
        if (NULL != result[i][j])
        {
            strcpy(result[i][j], "hello");
        }
    }
    printf("\n");
}

//Print the matrix
for (int i = 0; i < rows; i++)
{
    for (int j = 0; j < cols; j++)
    {
        printf("%s\t", result[i][j]);
    }
    printf("\n");
}

Ps: I'm using xCode with C99

The runtime error occurs here:

result[i][j] = (char *)malloc(100 * sizeof(char));

xCode returs me EXC_BAD_ACCESS

Mattia Merlini
  • 643
  • 1
  • 8
  • 24
  • You initialized `result` as an array of 10 `char**` elements. Then you filled the first 3 elements of this array with `char*` pointers, leaving the other 7 set to zero. Your runtime errors are occurring in the following nested loop, where you dereference all these null pointers and attempt to store text strings in them. – r3mainer Oct 02 '14 at 20:27
  • You're right, @squeamishossifrage. I inverted the concept. I'm beholden to you. Now all work. – Mattia Merlini Oct 02 '14 at 20:35

2 Answers2

1

This:

for (int i = 0; i < cols; i++)
{
    result[i] = calloc(cols, sizeof(char *));
}

should be this:

// -----------------here
for (int i = 0; i < rows; i++)
{
    result[i] = calloc(cols, sizeof(char *));
}

Unrelated: Stop casting memory allocation functions in C. This:

result[i][j] = (char*)malloc(100 * sizeof(char));

should just be this:

result[i][j] = malloc(100 * sizeof(char));

I found it odd this was here, since you correctly did not cast your calloc results.


Alternate Version: Variable Length Arrays (VLAs)

You can cut out one of your allocation loops by exploiting VLAs if your platform supports them. If done, the code would reduce to allocating the entire matrix of char* with a single calloc. For example:

int main()
{
    int rows = 10;
    int cols = 3;

    // create rows
    char *(*result)[cols] = calloc(rows, sizeof(*result));

    // load values into the matrix
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            result[i][j] = malloc(100 * sizeof(char));
            if (NULL != result[i][j])
            {
                strcpy(result[i][j], "hello");
            }
        }
        printf("\n");
    }

    //Print the matrix
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            printf("%s\t", result[i][j]);
        }
        printf("\n");
    }
}
Community
  • 1
  • 1
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • I tried your solution and all work. As I said to @squeamishossifrage I inverted the concept. I'm very grateful to you. Have a nice evening, you deserve it :)) – Mattia Merlini Oct 02 '14 at 20:37
0

In first for loop you are allocating memory only for 3 rows and you are trying to access more than 3 rows in your last loop.

µtex
  • 900
  • 5
  • 12