You need #include <stdio.h>
for printf
, and #include <string.h>
for memset
.
int main()
You can get away with this, but int main(void)
is better.
{
char *ptr;
char evil[4];
memset(evil, 0x43, 4);//fill evil variable with 4 C's
This would be more legible if you replaced 0x43
by 'C'
. They both mean the same thing (assuming an ASCII-based character set). Even better, don't repeat the size:
memset(evil, 'C', sizeof evil);
ptr = &evil[0];//set ptr variable equal to evil variable's memory address
This sets ptr
to the address of the initial (0th) element of the array object evil
. This is not the same as the address of the array object itself. They're both the same location in memory, but &evil[0]
and &evil
are of different types.
You could also write this as:
ptr = evil;
You can't assign arrays, but an array expression is, in most contexts, implicitly converted to a pointer to the array's initial element.
The relationship between arrays and pointers in C can be confusing.
Rule 1: Arrays are not pointers.
Rule 2: Read section 6 of the comp.lang.c FAQ.
printf(ptr);//prints 4 C's
The first argument to printf
should (almost) always be a string literal, the format string. If you give it the name of a char array variable, and it happens to contain %
characters, Bad Things Can Happen. If you're just printing a string, you can use "%s"
as the format string:
printf("%s\n", ptr);
(Note that I've added a newline so the output is displayed properly.)
Except that ptr
doesn't point to a string. A string, by definition, is terminated by a null ('\0'
) character. Your evil
array isn't. (It's possible that there just happens to be a null byte just after the array in memory. Do not depend on that.)
You can use a field width to determine how many characters to print:
printf("%.4s\n", ptr);
Or, to avoid the error-prone practice of having to write the same number multiple times:
printf("%.*s\n", (int)sizeof evil, evil);
Find a good document for printf
if you want to understand that.
(Or, depending on what you're doing, maybe you should arrange for evil
to be null-terminated in the first place.)
printf(&evil);//prints 4 C's
Ah, now we have some serious undefined behavior. The first argument to printf
is a pointer to a format string; it's of type const char*
. &evil
is of type char (*)[4]
, a pointer to an array of 4 char
elements. Your compiler should have warned you about that (the format string has a known type; the following arguments do not, so getting their types correct is up to you). If it seems to work, it's because &evil
points to the same memory location as &evil[0]
, and different pointer types probably have the same representation on your systems, and perhaps there happens to be a stray '\0'
just after the array -- perhaps preceded by some non-printable characters that you're not seeing.
If you want to print the address of your array object, use the %p
format. It requires an argument of the pointer type void*
, so you'll need to cast it:
printf("%p\n", (void*)&evil);
return 0;
}
Putting this all together and adding some bells and whistles:
#include <stdio.h>
#include <string.h>
int main(void)
{
char *ptr;
char evil[4];
memset(evil, 'C', sizeof evil);
ptr = &evil[0];
printf("ptr points to the character sequence \"%.*s\"\n",
(int)sizeof evil, evil);
printf("The address of evil[0] is %p\n", (void*)ptr);
printf("The address of evil is also %p\n", (void*)&evil);
return 0;
}
The output on my system is:
ptr points to the character sequence "CCCC"
The address of evil[0] is 0x7ffc060dc650
The address of evil is also 0x7ffc060dc650