Rafael Marinho
Rafael Marinho

Reputation: 3

Weird issue with malloc

I was doing a simple code to open a file with a matrix but I got a weird error. Here's my code:

char** CM;
char** ACM;
int lines, columns;
int i, j;

//read file
FILE* file = fopen("matrix.txt", "r");
fscanf(file, "%i %i", &lines, &columns);
CM = (char**)malloc(sizeof(char)*lines);
ACM = (char**)malloc(sizeof(char)*lines);
for(i=0; i<lines; i++)
{
    CM[i] = (char*)malloc(sizeof(char)*columns+1);
    ACM[i] = (char*)malloc(sizeof(char)*columns);
    fscanf(file, "%s", CM[i]);
    CM[i] = (char*)realloc(CM[i], sizeof(char)*columns);//don't need \n
    printf("%s\n", CM[i]);
}
printf("\n");
for(i=0; i<lines; i++)
{
    printf("%s\n", CM[i]);
}

But it happens that the output is not what I expected:

00000
01010
01010
01100
00000

��6
01010
01010
01100
00000

If I comment ACM[i] = (char*)malloc(sizeof(char)*columns); it works with no no problem. I even used GDB to see what was going on and I got this :

23          ACM[i] = (char*)malloc(sizeof(char)*columns);
2: CM[0][0] = 48 '0'
3: CM[1][1] = 49 '1'
4: i = 4
(gdb) 
24          fscanf(file, "%s", CM[i]);
2: CM[0][0] = -80 '\260'
3: CM[1][1] = 49 '1'
4: i = 4

Please, could someone tell me what's going on with my code?

Upvotes: 0

Views: 181

Answers (3)

R Sahu
R Sahu

Reputation: 206737

malloc(sizeof(char)*lines) allocates enough memory to hold line number of chars. You need enough memory to hold line number of char*s. Hence, you need to use sizeof(char*) instead of sizeof(char).

CM = (char**)malloc(sizeof(char*)*lines);
ACM = (char**)malloc(sizeof(char*)*lines);

As a matter of good coding practice, use:

CM = (char**)malloc(sizeof(*CM)*lines);    // CM  -> sizeof(*CM)
ACM = (char**)malloc(sizeof(*ACM)*lines);  // ACM -> sizeof(*ACM)

That would prevent errors of the kind you ran into.

Upvotes: 3

Stephan Lechner
Stephan Lechner

Reputation: 35164

With char **CM = (char**)malloc(sizeof(char)*lines) and char **ACM = (char**)malloc(sizeof(char)*lines), you allocate a sequence of characters, though you should allocate a list of pointers.

Write char **CM = (char**)malloc(sizeof(char*)*lines) and char **ACM = (char**)malloc(sizeof(char*)*lines) instead.

As a general rule, the return type (char** in your case) usually has one more star than the type inside the malloc, i.e. (char* in your case).

Note further, that in C you usually do not cast the result of malloc, whereas in C++ you have to cast. BTW: malloc is rarely used in C++.

Upvotes: 0

SoronelHaetir
SoronelHaetir

Reputation: 15182

In

ACM = (char**)malloc(sizeof(char)*lines);

You are allocating lines chars, not lines char*s

Upvotes: 0

Related Questions