-1

I have this lines:

char* data = (char *) mmap(NULL, size, PROT_READ, MAP_SHARED, fd, offset);
...
size_t lineLength = strlen(data);
char *out = calloc(lineLength, sizeof(data));

at the last line I get with the new XCode the following warning

Result of 'calloc' is converted to a pointer of type 'char', which is incompatible with sizeof operand type 'char *'

I stuck a bit is this a real complain?

Sebastian
  • 952
  • 1
  • 14
  • 41
  • 2
    There's no point in casting the return value of `mmap()`, in C. It's very much like [`malloc()`](http://stackoverflow.com/a/605858/28169): since it returns `void *` there's no need to cast. – unwind Jun 14 '13 at 07:21

2 Answers2

4

Yap, it is real. And it hasn't even discovered the entire problem.

When one dynamically allocates memory using the malloc() family of functions, which calloc() is the member of, for one element, the code often goes like so:

T *ptr = malloc(sizeof(T));

That's fine as long as you don't change the type of the pointer. When you do, you will forget to change the type in the sizeof(), and possibly you end up allocating less memory than your T type takes up, effectively making your program invoke undefined behavior.

And you just run into this issue. (Alhough, technically, here you allocate more memory than needed, no UB, but conceptually it's still wrong.)

char *out = calloc(lineLength, sizeof(data));

should really be

char *out = calloc(lineLength + 1, sizeof(*data));

instead. You want to allocate space for lineLength + 1 pieces of char, whereas data is a pointer-to-char.

Oh, and do not cast the return value of mmap()!

Community
  • 1
  • 1
2

you need to correct calloc() statement:

either:

char *out = calloc(lineLength, sizeof(*data));

(I think you need this as I can understand that you are allocating for string)

or

char **out = calloc(lineLength, sizeof(data));

depends on your need.

Additional point is allocate extra memory for NULL \0 symbol to terminate string. e.g. for fist case:

 char *out = calloc(lineLength + 1, sizeof(*data)); 
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
  • @Sebastian Because allocating more space than needed is not "harmful", it doesn't cause undefined behavior, it's just conceptually wrong. See my answer. –  Jun 14 '13 at 07:14
  • @GrijeshChauhan `sizeof(data*)` <-- what's that? –  Jun 14 '13 at 07:14