Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocating space of 1 char to an int pointer

Tags:

c

I am learning C and am a bit confused about why I don't get any warnings/errors from GCC with the following snippet. I am allocating space of 1 char to a pointer to int, is it some changes done by GCC (like optimizing the allocated space for an int silently)?

#include <stdlib.h>
#include <stdio.h>

typedef int *int_ptr;

int main()
{
  int_ptr ip;
  ip = calloc(1, sizeof(char));
  *ip = 1000;
  printf("%d", *ip);
  free(ip);
  return 0;
}

Update

Having read the answers below, would it still be unsafe and risky if I did it the other way around, e.g. allocating space of an int to a pointer to char? The source of my confusion is the following answer in the Rosetta Code, in the function StringArray StringArray_new(size_t size) the coder seems to exactly be doing this this->elements = calloc(size, sizeof(int)); where this->elements is a char** elements.

like image 473
Student Avatar asked Jan 25 '23 06:01

Student


1 Answers

The result of calloc is of the type void* which implicitly gets converted to an int* type. The C programming language and GCC simply trust the programmer to write sensible casts and thus do not produce any warnings. Your code is technically valid C, even though it produces an invalid memory write at runtime. So no, GCC does not implicitly allocate space for an integer.

If you would like to see warnings of this kind before running (or compilation), you may want to use, e.g., Clang Static Analyzer.

If you would like to see errors of this kind at runtime, run your program with Valgrind.

Update

Allocating space for 1 int (i.e. 4 bytes, generally) and then interpreting it as a char (1 char is 1 byte) will not result in any memory errors, as the space required for an int is larger than the space required for a char. In fact, you could use the result as an array of 4 char's. The sizeof operator returns the size of that type as a number of bytes. The calloc function then allocates that number of bytes, it is not aware of what type will be stored in the allocated segment.

While this does not produce any errors, it can indeed be considered a "risky and unsafe" programming practice. Exceptions exist for advanced applications where you´d want to reuse the same memory segment for storing values of a different type.

The code on Rosetta Code you linked to contains a bug in exactly that line. It should allocate memory for a char* instead of an int. These are generally not equal. On my machine, the size of an int is 4 bytes, while the size of a char* is 8 bytes.

like image 159
Yun Avatar answered Feb 02 '23 21:02

Yun