Here's the code -
#include <stdio.h>
int main()
{
char character_1 = '0';
int integer_1 = 12321;
char character_2 = '1';
char character_3 = '2';
printf("Integer occupies %zu byte(s) of space.\n",sizeof(int));
printf("Address of Integer 1: %p\n",(void*)&integer_1);
printf("\n");
printf("Character occupies %zu byte(s) of space.\n",sizeof(char));
printf("Address of Character 1: %p\n",(void*)&character_1);
printf("Address of Character 2: %p\n",(void*)&character_2);
printf("Address of Character 3: %p\n",(void*)&character_3);
printf("\n");
return 0;
}
and, the generated output -
Integer occupies 4 byte(s) of space.
Address of Integer 1: 000000000061FE18
Character occupies 1 byte(s) of space.
Address of Character 1: 000000000061FE1F
Address of Character 2: 000000000061FE17
Address of Character 3: 000000000061FE16
I want to print the addresses of all the four bytes of space occupied by the integer variable integer_1, which means print all four of these - 000000000061FE18, 000000000061FE19, 000000000061FE1A and 000000000061FE1B. How do I do it?
Is this what you are trying to do?
#include <stdio.h>
int main()
{
int integer_1 = 12321;
unsigned char* p = (unsigned char*)&integer_1;
for (int i=0; i<sizeof(int); i++){
printf("Address: %p -> Value: %02hhx\n", p+i, *(p+i));
}
return 0;
}
EDIT: As pointed out by KPCT, working with void* is indeed possible, just a bit more tedious if you are also interested in the value pointed, and not the address only.
For example, adapting my above solution to use void*, would result in something like this
#include <stdio.h>
int main()
{
int integer_1 = 12321;
void* p = (void*)&integer_1;
for (int i=0; i<sizeof(int); i++){
printf("Address: %p -> Value: %02hhx\n", p+i, *((char*) p+i));
}
return 0;
}
where you would have to go through the cast to char* anyway
You would need to cast the int pointer to a char pointer (or an int8_t pointer), then step through each of the bytes, something like this:
char *cp = (char*)&integer_1;
for (int i = 0; i < sizeof(integer_1); ++i)
printf("Address of integer_1, byte %d: %p\n",i,cp++);
Related
I am typecasting the address of a character variable whose address 0x7ffc684486ef to an integer pointer. The value at the address 0x7ffc684486ef is 16, when I dereference using the integer pointer it would read 4 bytes starting from address 0x7ffc684486ef, but it return value 0, how is it. Is my understanding wrong ?.
int main()
{
char var;
int *ptr;
ptr = (int *)&var;
printf("%p %p\n", &var, ptr);
*ptr = 16;
printf("%d %d\n", var, *ptr);
return 0;
}
O/P
0x7ffc684486ef 0x7ffc684486ef
16 0
Why the below code does not print anything.
#include <stdio.h>
#define ADDRESS 0x7ffc684486ef
typedef struct Point {
int x;
int y;
}Point;
int main()
{
Point *var = (Point *)(ADDRESS);
var->x = 2;
var->y = 5;
printf("Location: %p\n", var);
printf("Values: %d %d\n", var->x, var->y);
}
O/P:
NIL
C allows wildly unsafe pointer conversion such as ptr = (int *)&var; without protesting. So it's likely that you get the same address even after changing the pointer type.
However, when you de-reference the *ptr = 16; you invoke an impressive number of undefined behavior bugs: out of bounds access, possible misaligned access, strict aliasing violation, accessing memory you don't have access to, and so on. Don't do this, this code is incredibly broken and there's no telling what the result might be. What is undefined behavior and how does it work?
The second example is even worse:
How do you know there is memory you have access to at that address?
It's a misaligned address so you can't access it as a struct on most computers
The access of memory areas unknown by the compiler, such as hardware registers, has to be volatile qualified.
So it would seem that you make a misaligned address somewhere out in la-la-land and this too is wildly undefined behavior. There's no point in reasoning about any behavior you might encounter. Any form of behavior can happen.
Just to clarify the concept related to *p = 16 ...
Look at this piece of code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int numa = -1, num, numb = -1;
int *p = (int *)#
*p = 16;
printf("\n%d %d %d %d", *p, numa, num, numb);
}
When it runs it will output:
16 -1 16 -1
Now try changing the data type to char on the line that declares 'num':
#include <stdio.h>
#include <stdlib.h>
int main()
{
char numa = -1, num, numb = -1;
int *p = (int *)#
*p = 16;
printf("\n%d %d %d %d", *p, numa, num, numb);
}
you will receive "Segmentation fault".
When I try to print this
#include <stdio.h>
int main(){
int x = 3;
int *ptr = &x;
//printf("Address is : %d\n",&ptr);
ptr++;
*ptr = 1;
printf("%d %d",x,ptr);
return 0;
}
The code outputs 3 1, shouldn't it be 3 (then address of ptr?). Then, when I uncomment first printf it prints out:
Address is : 6356744
3 6356752
Does anyone know what is going on?
You have several serious problems in your code.
1) You print a pointer value or an address of a variable using %d but should not. That is undefined behavior so we can't know what will happen. To print a pointer value or an address of a variable use %p and cast to a void pointer like:
printf("Address is : %p\n",(void*)&ptr);
2) You write to memory that is not allocated to your program. These lines:
ptr++;
*ptr = 1;
make you write the value "1" one step past x. So this is also undefined behavior.
Correction the above could give you this program:
#include <stdio.h>
int main(){
int x = 3;
int *ptr = &x;
printf("Address is : %p\n",(void*)&ptr);
ptr++;
// *ptr = 1;
printf("%d %p\n",x,(void*)ptr);
return 0;
}
With the possible output:
Address is : 0x7ffc5b0923c8
3 0x7ffc5b0923c8
but the output may change from run-to-run and system-to-system
I keep getting this warning
c:9:80: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
printf("Char= %c ASCII = %i hex = %x pointer = %p \n", i, i, i , (void*)i );
Code
#include<stdio.h>
int main (void) {
int *i;
for (int i = 75; i < 75 + 26; i++) {
printf("Char= %c ASCII = %i hex = %x pointer = %p \n", i, i, i , (void*)i );
}
return(0);
}
I fail to see what the question might be that is not answered by the compiler warning. You've got a variable "i" of type int (32 bit on 64 bit platforms), shadowing another variable called "i" in the main program.
You're casting the int variable to void*, and the compiler says you can't do that, because you are 32 bit short. Rename one of the two variables called i in your program to resolve.
You’re getting the warning because the variable “i” is declared twice in the same scope. The memory address of ‘i’ in your loop doesn’t change so what do you need the pointer outside the loop for?
#include<stdio.h>
int main (void) {
for (int i = 75; i < 75 + 26; i++) {
printf("Char= %c ASCII = %i hex = %x pointer = %p \n", i, i, i , &i );
}
return(0);
}
or yet still if you still want to have two variables.
#include<stdio.h>
int i;
int *j = &i;
int main (void) {
for ( i = 75; i < 75 + 26; i++) {
printf("Char= %c ASCII = %i hex = %x pointer = %p \n", i, i, i , (void *)j );
}
return(0);
}
I'm trying to write into a byte that I have allocated using malloc(). I'm really struggling with correctly printing out the bits and the values.
int main(){
unsigned char *heap = (unsigned char *) malloc( 2 * sizeof(char)); //allocate two bytes
int n= 2, i =0;
unsigned char* byte_array = heap;
while (i < 2) //trying to write over the first byte then print out to verify
{
printf("%016X\n", heap[i]);
heap[i] = "AAA";
printf("%p\n", heap[i]);
i++;
}
}
This is the output I'm getting
0000000000000000
0xc7
0000000000000000
0xc7
To understand difference between "string" and 'c' character in C. Try this code:
#include <stdio.h>
int main(){
/* Usual way */
char *a = "A";
char *b = "B";
char *c = "C";
printf("Address of a = 0x%x\n",a);
printf("Address of b = 0x%x\n",b);
printf("Address of c = 0x%x\n",c);
/* Explicit way - Because you asked above question */
printf("This is Base Address of String A = 0x%x\n","A");
printf("This is Base Address of string B = 0x%x\n","B");
printf("This is Base Address of string C = 0x%x\n","C");
/* Now, let us print content - The usual way */
printf("Pointer value a has %x\n",*a);
printf("Pointer value b has %x\n",*b);
printf("Pointer value c has %x\n",*c);
/* The unusual way */
printf("Value of String A %x\n",*"A");
printf("Value of String B %x\n",*"B");
printf("Value of String C %x\n",*"C");
}
The above code will generate compiler warning because char * is formatted as unsigned int, but just ignore it to understand the example.
The output would look like following:
Address of a = 0xedfce4a
Address of b = 0xedfce4c
Address of c = 0xedfce4e
This is Base Address of String A = 0xedfce4a
This is Base Address of string B = 0xedfce4c
This is Base Address of string C = 0xedfce4e
Pointer value a has 41
Pointer value b has 42
Pointer value c has 43
Value of String A 41
Value of String B 42
Value of String C 43
First of all, you are doing some operations without really knowing the meaning:
while (i < 2)
{
printf("%016X\n", heap[i]); // You're printing the value of heap[i] in hexadecimal that
// is not even setted
heap[i] = "AAA"; // This operation has no sense, 'cause a
// "char" can only contain 1 character
printf("%p\n", heap[i]); // You are printing a pointer, why?
i++;
}
The char in C can contain only ONE character. So this has a sense:
char a = 'b';
and if you want to have a string you need an array of char:
char * a = "AAA";
For more read here
So I would rewrite the code in this way:
while (i < 2){
printf("First: %c\n",heap[i]);
heap[i] = 'a';
printf("After: %c\n",heap[i]);
i++;
}
Just for educational purpose I have written C code that gets out of array bound:
int main( int argc, char ** argv ) {
char *cp = "dabsf";
cp=cp+10;
printf("%c",*cp);
return 0;
}
I have letter n in output.
Is it possible somehow to see whole memory map and see what bytes are near cp array and find where is n?
I'm using MinGW compiler.
Here's some code to print memory out, you can use it to print memory around after any pointer you want (trying to print too much might give you an access violation, especially trying addresses before your first variable):
#include <stdio.h>
void printMemory(void *address, int rows, int cols) {
for(int r = 0, c; r < rows; ++r) {
c = 0;
printf("%8p ", (void *)(((unsigned int*)address) + (r*cols + c)));
for(; c < cols; ++c) {
printf("0x%08x ", *(((unsigned int *)address) + (r*cols + c)));
}
printf("\n");
}
}
int main(void) {
char *test = "Hello World!";
unsigned int value1 = 0xABABABAB;
unsigned int value2 = 0xDEADBEEF;
unsigned int value3 = 0xCAFEBABE;
printf("%s, %d, %d, %d\n", test, value1, value2, value3);
printMemory(test, 4, 2);
printf("\n");
printMemory(&value1, 1, 3);
return 0;
}
The output is (in my case the string was stored in a different place than the integers):
Hello World!, -1414812757, -559038737, -889275714
0x80486ad 0x6c6c6548 0x6f57206f
0x80486b5 0x21646c72 0x2c732500
0x80486bd 0x2c642520 0x2c642520
0x80486c5 0x0a642520 0x01000000
0xbf8aab50 0xabababab 0xcafebabe 0xdeadbeef
Also this works for debugging, but do not do this in real code, accessing memory addresses that aren't for your variables is undefined behavior.
To print the memory map of 10 positions from cp:
#include <stdio.h>
int main(void) {
int i;
char *cp = "dabsf";
printf("Address of 1st element of cp %p\n", cp);
for(i=1;i<=10;i++)
{
printf("Address of %c is %p\n",*(cp+i), cp+i); // cp+i is the same as &(*(cp+i))
}
return 0;
}
To get the address of any element after the array:
cp = cp + 8;
printf("Element at cp+8 is %c\n", *cp);
printf("Address of cp+8 is %p\n", cp);
Note: the output of the code just above may change in successive runs of the code.