Could you please explain me memory allocation in C for strings and integer array?
Most of the time in C, memory allocation is your responsibility. In particular, when you call functions such as strcpy
, sprintf
and fread
, that write potentially arbitrarily many characters to a buffer you supply, it is your responsibility to ensure, somehow, beforehand, that the buffer is big enough.
Some functions, such as fread
, let you say how big your buffer is, so that they can be sure not to overflow it. Others, such as strcpy
, sprintf
, and scanf
with directives like %s
, do not. You must be especially careful with these functions.
When you write something like
char str[10];
sprintf(str, "%lld", 7564368987643389);
where you supply a buffer that is not big enough for the result, two questions tend to arise:
Why didn't it work?
Why did it work?
If it didn't work, the reason why should be obvious: the destination buffer simply wasn't big enough. And if despite that problem, it did seem to work, the reason is because C doesn't typically enforce (doesn't explicitly guard against) buffer overflow.
Suppose I buy some land -- a 1600 square foot plot -- in an undeveloped neighborhood. Suppose my title deed says:
The property line runs south for 40 feet from an iron stake, then 40 feet west, then 40 feet north, then 40 feet east.
So I've got 40 x 40 foot plot of land, but the only feature on the ground that positively identifies where my property is, is an iron stake at one corner. There isn't a crisp black line painted on the soil, or anything, precisely delineating the property lines.
Suppose I hire an architect and a builder, and we build a house on my new plot of land, and we screw up our measurements, and we build the house 10 feet into a neighboring parcel of land (that I don't own). What happens?
What does not happen is that the instant we dig that first footing or pour that first concrete or erect that first wall that crosses over the property line, a giant error message appears in the sky saying "PROPERTY LINE EXCEEDED".
No, this kind of error is not guaranteed to get detected right away. The problem might not be noticed (by a building inspector, or by the owner of the adjacent property) until tomorrow, or next week, or next year; and under some circumstances it might never get noticed at all.
And the situation is just about exactly the same with C memory allocation. If you write more to an array than it's allocated to hold, the problem might not reveal itself for a while, or it might not reveal itself at all: the program might seem to work perfectly, despite this reasonably dire error it contains.
For this reason, not only do you have to be careful with memory allocation in C, there are some good habits to get into. Not only is it important to declare you arrays (or malloc your buffers) big enough, but you also want to make sure that, whenever possible, the size is checked. For example:
When you call functions like fread
, that accept a destination buffer and the size of that buffer, make sure the size you pass is accurate.
Instead of calling functions like sprintf
that accept a destination buffer but with no way to specify its size, prefer alternative functions like snprintf
that do allow the size to be specified and that therefore can guard against overflow.
If there's a function that doesn't allow the buffer size to be specified and for which there's no better alternative, maybe just don't use that function at all. Examples are strcpy
and scanf
with the %s
and %[
directives.
When you write your own functions that accept pointers to buffers and that write characters or other data into those buffers, make sure you provide an argument by which the caller can explicitly supply the buffer size, and make sure your function honors this limit.