In the book Learn C The Hard Way at excercise 15 there is suggestion to break program by pointing integer pointer at array of strings and using C cast to force it. How can I do it?
-
Why do you want to do it? – August Karlstrom Jan 15 '16 at 11:10
-
You already say how to do it (“using C case”). What is your question? – fuz Jan 15 '16 at 11:18
-
1@FUZxxl I'm beginner at C so I don't know how to do it with casting types. – Nikola Stojaković Jan 15 '16 at 11:20
-
@AugustKarlstrom There is a section in every lession at given book where you can find suggestions for breaking program and making willing compiler errors. – Nikola Stojaković Jan 15 '16 at 11:21
-
@Nikola Do you have an array of strings or characters? – Jan 15 '16 at 11:21
-
@Ehsan Nope, array of strings. You can see that double level pointer is used at exercise (pointing to array with strings). – Nikola Stojaković Jan 15 '16 at 11:23
-
1C compilers never give error in casts ( maybe C++ compilers give it depends on the compiler ) – Jan 15 '16 at 11:24
-
They don't give errors because wild pointer casts is undefined behavior, which always occurs at run-time. – Lundin Jan 15 '16 at 12:11
-
@Ehsan Oh yes, they do. Try `(int*)1.0`. – fuz Jan 15 '16 at 15:27
-
bro I didn't wrote completely yes of course converting a double to pointer but in conversion of pointer types they don't give errors because pointers ( not long pointers ) are all 4 bytes. – Jan 16 '16 at 11:37
-
@Ehsan I've talked about section in the book, not about giving compiler errors through casts. – Nikola Stojaković Jan 16 '16 at 12:11
4 Answers
Here is a small example. the result depends on the endianness of your system and the size of int
. I would expect the first or fourth character to change to the next character in the alphabet.
#include<stdio.h>
int main(void) {
char string[100] = "Somestring";
int *p;
/* Let p point to the string */
p = (int*)string;
/* modify a value */
(*p)++;
/* Let's see if any character got changed */
printf("%s", string);
return 0;
}
It should be pointed out that not all casts are safe and that the result could be implementation defined or undefined. This example is actually undefined, since int
could have stricter alignment constraints than char
.
When writing portable code you need to take great care when using casts.
The code above could break on any system where sizeof(int)
is greater than the string length regardless of alignment issues. In this case, where the string has size 100, we wouldn't expect that to happen in a long while. Had the string been 4-7 bytes it could happen sooner. The jump from 32- to 64-bit pointers broke a lot of old code that assumed that pointers and int
were the same size.
Edit:
Is there an easy fix to the alignment problem? What if we could somehow make sure that the string starts in an address that is also suitable for an int
. Fortunately, that is easy. The memory allocation function malloc
is guaranteed to return memory aligned at an address that is suitable for any type.
So, instead of
char string[100] = "Somestring";
we can use
char *string = malloc(100);
strcpy(string, "Somestring");
The subsequent cast is now safe alignment-wise and is portable to systems where int
is smaller than 100.
Note that malloc
is declared in stdlib.h
, so we should add the following at the top of our code file:
#include<stdlib.h>

- 33,105
- 5
- 57
- 82
-
1That could even crash on some hardware where alignment constraints matter (not x86). – Basile Starynkevitch Jan 15 '16 at 11:27
-
@BasileStarynkevitch That's the point of the exercise the OP is reading - he's just asking about the particular syntax of doing it. – nos Jan 15 '16 at 11:32
-
@BasileStarynkevitch I've added a couple of paragraphs on the perils of casting. – Klas Lindbäck Jan 15 '16 at 11:51
-
1Also I believe this breaks the strict aliasing rule. You can go from _type_ to character, not the other way around. – Lundin Jan 15 '16 at 12:08
That's simply an abusive way of casting.
// setup the pointers to the start of the arrays
int *cur_age = ages;
char **cur_name = names;
What the author of that link meant by "to break program by pointing integer pointer at array of strings and using C cast to force it." He meant that you can write something like this int *cur_age = (int *)names;
That is to cast a pointer to pointer to char to a pointer to int. You can do that in C, which allows you to cast from one type of pointer to another type of pointer; but be warned you need to know what you are doing.
Here the author wanted to show how to break a program by pointing a pointer to a wrong type. His example, however, is probably making you more confused rather than helping you to understand pointers.

- 17,291
- 6
- 38
- 54
To cast, use the cast operator: (type)expression
. For example, to cast an expression of type double
to int
:
(int)sqrt(2);
In your specific case, cast names
to int*
(the type of cur_age
) to break the program:
cur_age = (int*)names;

- 88,405
- 25
- 200
- 352
To point incompatible pointer in c you only need to cast it to void.
//array of string declaration
char aStr[50][50];
Int *pint;
//do whatever you need with string array
pint = (*int)(*void)aStr;
I'm writing this from my cell phone.
if you increment your pointer past the allocated memory, you might end up in your program stack and change value to it.

- 1
- 1
-
1This would violate [strict aliasing](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule). – Lundin Jan 15 '16 at 12:08