Code:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i = 1;
char buf[4];
strcpy(buf, "AAAA");
printf("%d\n", i);
return 0;
}
Printable View
Code:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int i = 1;
char buf[4];
strcpy(buf, "AAAA");
printf("%d\n", i);
return 0;
}
Probably because you allocated 4 bytes for buff but wrote 5 bytes with the strcpy(). The 5th byte very likely over wrote part of the memory that i uses.
Indeed. Don't forget that strings in C have a null character assumed at the end.
Code:#include <stdio.h>
#include <string.h>
int main(void) {
int i = 1;
char buf[4];
strcpy(buf, "AAA\0");
printf("%i\n", i);
return 0;
}
Kleid-0 - the null character is assumed.
And infact your string literal still assigns 5 bytes.
YAArrrrr... I should have known. Thanks guys.
But when declaring variables, is the memory always assigned in contiguous blocks? Any links to more info on these kinds of details?
> is the memory always assigned in contiguous blocks?
Whether i is before or after buf in memory is implementation specific.
How much space is between variables in memory is also implementation specific.
Correct code should rely on neither of these.
> Correct code should rely on neither of these.
Yeah, I am aware of this. I just wanted to know more about how exactly memory is allocated when declaring variables in C.
Ofcourse its not a good idea to use unallocated space.
Compilers may make a difference, but the OS is also a major factor.
Typically (I took this example from windows), you'll see that memory is organized similar to this...
-Storage (uninitialized) variables <---- High Address
-Static Variables
-Read Only
-Constants (not user accessible)
-Code (program instructions)
-Heap
-Stack
-OS reserved <---- Low Address.
So for example, if you take your original code (with the error) and initialize variable i as static...you'll find that you receive the output you were looking for (obviously there is still an error in the program, just not as apparent).Code:static int i = 1;
I believe OS is included in "implementation" - but that's good information ;)Quote:
Compilers may make a difference, but the OS is also a major factor.
dangit! Well at least the output was not 0! :pQuote:
Originally Posted by sean_mackrory
Does it?Quote:
Originally Posted by Thantos
Bah you're right it would stop at the first null character :) Shows you how often I use strcpy now that I'm using C++ almost full time ;)Quote:
Originally Posted by Dave_Sinkula
This question cannot be directly answered since memory is not allocated by C, it is allocated by the OS. That said, I can explain how the memory most likely was allocated on your system to give you the results you got.Quote:
Yeah, I am aware of this. I just wanted to know more about how exactly memory is allocated when declaring variables in C.
In your code, the above declarations are the ones that are requesting memory. You are requesting space for 1 integer, and 4 chars. On 99% of the computers in use today, integers are 4 bytes, and characters are 1 byte each. Keep in mind though that these memory sizes are not standard at all. An integer could be 8 bytes on some machines (new 64 bit processers for instance), and a char could be 2 bytes or some other values.Code:int i = 1;
char buf[4];
The memory allocated in your program is allocated on what's called the stack. First the 4 bytes for the integer are pushed onto the stack, then the 4 bytes for the char array. Here is a small diagram:
Now first, i is assigned the value of 1. Now our stack looks like:Code:Top of stack on left, bottom of stack on right:
[ ][ ][ ][ ][ ][ ][ ][ ]
| chars | integer |
Now you may ask yourself why is the number 1 stored as 0x1000 instead of 0x0001? The answer is that many processers store data in little endian format. This means that the least significant byte goes first.Code:Top of stack on left, bottom of stack on right:
[ ][ ][ ][ ][1][0][0][0]
| chars | integer |
Next you perform:
Keep in mind strcpy automatically places a trailing null terminator at the end of the string. Now your stack looks like (assuming ASCII character set):Code:strcpy(buf, "AAAA");
Notice the trailing null terminator overwrote the least significant byte of your integer.Code:Top of stack on left, bottom of stack on right:
[41][41][41][41][0][0][0][0]
| chars | integer |
This explains a little bit about what goes on "under the hood". It doesn't actually have much to do with the C programming language, but I think it's good stuff to know :)