I am working in a program using the DWARF and ELF info. I am hooked to another program using a tool called Pin. I have the addresses from the global variables declared in "Y" program and I hook it into my Pin module which I will call "X".
I am getting a bunch of addresses for these global variables. Unfortunately I am having troubles when I try to dereference them. For example (right now I am doing things manually to see if it is doing what is supposed to be doing):
char * limit, * address1;
for(address1 = (char *) 0x804A040, limit = address1 + bytesize; address1 < limit; address1++)
cout << *(address1) << "\n";
I should be getting the variable that is stored in that address which is a char * to a word. Do I have to dereference two pointers in this case? The address and then the char * stored in that address?
This works perfectly fine when I want to dereference an int variable, but whenever I try to dereference a char pointer or variable I get non-ASCII values...
Think like this: if you want to dereference an int, you use int *:
int *addr = (int *)0x12345678;
printf("%d\n", *addr);
But a string is already a pointer, so if you do this:
char *addr = (char *)0x12345678;
You don't need to dereference it to print it out, so you get it this way:
printf("%s\n", addr);
Additionally, suppose you have this memory:
00000001: 0x12345678
...
12345678: 'A'
12345679: 'B'
1234567A: '\0'
...
Let's access the address 0x00000001 and see what we can do:
unsigned int *addr = (unsigned int *)0x00000001;
Now *addr holds an integer which is the address of the first character of our string. Functions that take a string argument, usually ask for the string address, that is, a pointer to it, so *addr is also the string we should print on cout or printf for example.
// This should print "AB"
printf("%s\n", (char *)(*addr));
Now if you dereference our value (0x12345678), we'd get the string's first character, and only it, as a char. So if you misuse it and dereference it to a char *, printf would try to search for the memory 'A', which is 0x00000041, and would probably get a segmentation fault.
So, the right way to dereference its value, to get the first character would be this:
// This should print "A"
printf("%c\n", (char)(**addr));
So, as a conclusion, if you are still getting non-ASCII values, that's probably an issue with this kind of hierarchy between addresses, and I would recommend you to strictly debug the memory and see if creating a pointer to a pointer is the right path to your string.
Yes, you need to dereference two pointers. First to get the address of the variable that holds the char*, and then to dereference the char*.
Related
I initialized a char and a pointer, and then point it to the char. But I found that only the first character in the char was passed into the pointer. How could this be? Appreciate any advice!
char p[]="This is a long char.";
std::cout<<sizeof(p)<<"\n";
char *ptr=p;
std::cout<<*ptr<<"\n";
Got:
21
T
Program ended with exit code: 0
When checking the value of variables I noticed that:
ptr=(char *) "This is a long char."
*ptr=(char) 'T'
Why is the ptr holding the whole char but the content in it is only the first character? Isn't this the opposite of what we call a pointer? Got really confused...
When you said:
std::cout<<*ptr...
you dereferenced ptr, which gives you the (first) character that ptr is pointing to.
flyingCode's answer shows you how to print the entire string.
In C++, an array is just like multiple variables grouped together, so they each have a memory address, but they are one after another.
So, the pointer is pointing at the address of the first element, and the other elements are in the adresses right after that in order.
When you use the * operator on a pointer, it references the contents of the memory address the pointer is pointing to.
If you wanted to access another element of the array using this, you would use *(ptr + 5) to offset the memory address.
When you use the variable name alone, the language just does the offset for you and gets all the contents of the array. The pointer doesn't know the length of the array, but it can find the end of it, because char arrays always end with a null character (\0).
ran your code in repl and changing it to the code below worked :D
char p[]="This is a long char.";
std::cout<<sizeof(p)<<"\n";
char *ptr=p;
std::cout<<ptr<<"\n"; //notice no *
I recommend you use std::string rather than c-strings unless you have a specific need for them :)
I have the following simple piece of code,
unsigned long the_function(const char* p){
int* ip = (int*)p;
printf("%d\n",ip);
}
I know that the first line cast is meaning less but that the code given to me.
Now when i just pass "a" to the function i get the constant output
4196024
could someone explain to me what is the meaning.
It's printing the address of the string.
You're attempting to print the address of the pi pointer which is of type (int *). The address is represented with 8 bytes, but ints may be represented with 4 bytes, so when you attempt to print pi using %d only a portion of the pointer is printed. As Remy Lebeau pointed out using %p is the correct way to print a pointer address.
As an aside, you're converting the char * pointer to a type of int * but you never try to access the value of what int * is pointing at, in case that's what you were trying to do.
#include <iostream>
using namespace std;
int main() {
int * a[5];
char * b[5];
cout<<a[1]; // this works and prints address being held by second element in the array
cout<<b[1]; // this gives run time error . why ?
return 0;
}
Can anyone please explain to me cout<<b[1] gives run-time error ?
Shouldn't both int and char array behave similar to each other ?
Because IOStreams are designed to treat char* specially.
char* usually points to a C-string, so IOStreams will just assume that they do and dereference them.
Yours don't.
As others have said, iostream formatted output operators consider char* to point to C-style string and attempt to access this string.
What others have not said so far, is that if you are interested in the pointer, you need to cast the pointer in question to void*. For example:
std::cout << static_cast<const void*>(buf[1]);
An output stream such as cout gives special consideration to char * that it does not give to other pointers. For pointers other than char *, it will simply print out the value of the pointer as a hexadecimal address. But for char *, it will try to print out the C-style (i.e. null terminated array of char) string referred to by the char *. Therefore it will try to dereference the char pointer, as #AlexD points in the comment to your post.
C++ (inheriting it from C) treats character pointers specially. When you try to print a[1] of type int* the address is printed. But when you try to print b[1] of type char* the iostream library - following the rest of the language - assumes that the pointer points to the first character of zero-terminated string of characters. Both your output statements are initialised behaviour, but in the case of char* crash is much more likely because the pointer is dereferenced.
#include <iostream>
using namespace std;
void test_func(char *data,int length)
{
cout<<"data:"<<data<<endl;
cout<<"length:"<<length<<endl;
void *addr=data;
cout<<"*addr:"<<addr<<endl;
cout<<"Address of data:"<<&data<<endl;
cout<<"data again:"<<*(&data)<<endl;
}
int main()
{
char msg[]="Hello world!";
test_func(msg,6);
return 0;
}
I was trying some other program where I came accrross void *addr=data. so I tried to understand it by writing a separate program for it. And here I am not able to understand what is the value stored in addr. I got the output of following program as:
data:Hello world!
length:6
*addr:0x794e0553d310
Address of data:0x794e0553d2e8
data again:Hello world!
Any help would be appreciated. Thanks in advance.
operator << is overloaded for cout, so if you pass a char* it prints the content (even though char* is a pointer).
However, if you pass a void pointer (addr in your example) it will print the address itself. So addr is the address of the first element of the message.
On the other hand, &data is a pointer to a pointer, so cout prints the address of data (with data being a pointer to your message).
When an array designator is passed to a function as an argument it is converted to a pointer to its first element.
Function parameters are local variables of the function.
Thus you can imagine function test_func along with its call as test_func(msg,6); the following way
void test_func( /* char *data,int length */)
{
char *data = msg;
int length = 6;
cout<<"data:"<<data<<endl;
cout<<"length:"<<length<<endl;
void *addr=data;
cout<<"*addr:"<<addr<<endl;
cout<<"Address of data:"<<&data<<endl;
cout<<"data again:"<<*(&data)<<endl;
}
In this case expression &data used in statement
cout<<"Address of data:"<<&data<<endl;
is the address of function local variable data
Accotding to the output
Address of data:0x794e0553d2e8
variable data is placed at address 0x794e0553d2e8 inside the function. The variable itself contains the address of the first character of array msg because it was assigned such a way when the function was called.:)
char *data = msg;
So the address of the variable data and the value stored in the variable differ.
As for this expression
*(&data)
then it is equivalent to expression
data
Thus statement
cout<<"data again:"<<*(&data)<<endl;
outputs the string the address of the first character of which is stored in pointer data.
operator << is overloaded for pointers of type char * It considers the object pointed to by such a pointer as a string and outputs it accordingly. Take into account that &data has type char **. It is not the same as char *. So for pointers of type char ** (and of other types) there is used overloaded operator << that interpretates such pointers as const void * and simply outputs the corresponding value.
data is a pointer to the first char of a string, which is how strings are implemented in C. When you assign it to addr, you are just getting rid of the static type of data.
The reason you get different results when you output addr and data is that std::cout treats char* as a special case: it is output as a string rather than having its pointer value printed. void* doesn't share this, so you just see the address.
void *addr=data"
When you write above statement, addr is a pointer of type void* and which has an address in memory. And it will be different from the address of the variable data of type char*. So when you print as follows
cout<<"*addr:"<<addr<<endl;
cout<<"Address of data:"<<&data<<endl;
Each statement will print corresponding address of those variables.
*addr=data;
The above statement will not change the address of variable addr instead it will redirect the address location of addr to the address location of data.
Why does the following happen?
char str[10]="Pointers";
char *ptr=str;
cout << str << "\n"; // Output : Pointers
int abc[2] = {0,1 };
int *ptr1 = abc;
cout <<ptr1 << "\n"; // But here the output is an address.
// Why are the two outputs different?
As others have said, the reason for the empty space is because you asked it to print out str[3], which contains a space character.
Your second question seems to be asking why there's a difference between printing a char* (it prints the string) and int* (it just prints the address). char* is treated as a special case, it's assumed to represent a C-style string; it prints all the characters starting at that address until a trailing null byte.
Other types of pointers might not be part of an array, and even if they were there's no way to know how long the array is, because there's no standard terminator. Since there's nothing better to do for them, printing them just prints the address value.
1) because str[3] is a space so char * ptr = str+3 points to a space character
2) The << operator is overloaded, the implementation is called depending on argument type:
a pointer to an int (int*) uses the default pointer implementation and outputs the formatted address
a pointer to a char (char*) is specialized, output is formated as a null terminated string from the value it points to. If you want to output the adress, you must cast it to void*
The empty space is actually Space character after "LAB". You print the space character between "LAB" and "No 5".
Your second question: You see address, because ptr1 is actually address (pointer):
int *ptr1;
If you want to see it's first member (0), you should print *ptr1