char mening[] = "tjena pa dig hog";
This string contains 16 characters. I am then using a function adresss() to find the memory address of a random character in that array. The function adresss() returns a pointer containing the address. The address is at this moment 0x7ffeefbff5f9.
I now need to know what positions that address is pointing to, example is it pointing to the "t" at position 0 in the array, or maybe it is pointing to "d" at position 9. How do I do this?
Edit:
char* adresss(char mening[]){
//Lots of code going on here
return &mening[i];
}
int main(void){
char mening[] = "tjena pa dig hog";
char* ptr;
ptr = adresss(mening);
printf("%p\n", ptr);
That is basically how I get the memory adress. I want to know what "i" was, inside the main function only knowing the memory adress.
If you have two pointers, both pointing to the same array (or to one beyond the end of the array), then you can subtract them from each other.
For example:
char mening[] = "tjena pa dig hog";
char *pointer_to_mening = &mening[10]; // Pointer to the eleventh character
// Should print 10 (which is the index of the eleventh character)
printf("The distance is %zu\n", pointer_to_mening - mening);
Related
I am really struggling with pointers in C. Specifically, I have been having trouble understanding how to work with pointers when they are in main versus when I input a pointer into a function parameter from main.
I have a few scenario questions about them that hopefully someone can answer:
int main (int argc, char* argv[]) {
int x = 7;
int* num = 4;
char* word = "johnny";
//Q1. how do I get the address of 'num'?
//Q2. how do I get the address of 'x'? (should I be using x's or num's address?)
//Q2. how do I get the value of 'num'?
//Q3. how do I get the address of 'word'?
//Q4. how do I get the whole string for 'word'?
//Q5. how do I get an individual character in 'word'? (for index 0 ('j') and index 3 ('n'))
}
bool some_func (int* count, char** name) {
//Q6. how do I get the address of the inputted 'count'?
//Q7. how do I get the value of the inputted 'count'?
//Q8. how do I get the address of the inputted string 'name'?
//Q9. how do I get the whole string of the inputted string 'name'?
//Q10. how do I get an individual character of the inputted string 'name'? (for index 0 ('j') and index 3 ('n'))
}
For my recent homework assignments, I've been given intimidating headers like these and I don't know how to get the values that I want out of them. Say I found out that saying '*name' got me the whole string, where do I go from there?
If someone could answer all of the questions in the code I think that would probably be the best way of learning it since it's through example. Thanks!
Firstly, when you declare int* num, you created a pointer. You cannot assign a value directly to a pointer. What you could do is declare a variable, like you did for int x, and point the pointer to variable x (hence the name pointer) by using num = &x (&x refers to address of x, and is assigned to num) To get the value of num, you will have to use *num. Below is an example:
int *num;
int a = 4;
num = &a;
printf("address of a is %p, and value of a is %d", num, *num);
Output to first example:
address of a is <0xsome address> , and value of a is 4
As for characters, same thing you can't assign a value directly to pointer (like you did in char* word = "johnny";. A concept I think you should know is that "johnny" is a String, and strings are essentially an array of characters, hence each character of the string has its own address. Using similar to previous example:
char* word;
char someString[6] = "johnny";
word = &someString[0];
printf("address of first char of someString is %p, 1st char of someString is %c, 2nd char of someString is %c", word, *(word), *(word+1));
Output for the second example:
address of first char of someString is <0xsome address>, 1st char of someString is j, 2nd char of someString is o
Importing thing to note is that when accessing each character of the string using de-referencing of pointers, the +n must be inside the bracket with the pointer word.
*word+1 //WRONG
*(word+1) //CORRECT
Hope this gives you a base foundation of what you will need to tackle the rest of the questions!
#include <stdio.h>
const int MAX = 4
int main () {
char *names[] = {
"Zara Ali",
"Hina Ali",
"Nuha Ali",
"Sara Ali"
};
int i = 0;
for ( i = 0; i < MAX; i++) {
printf("Value of names[%d] = %s\n", i, names[i] );
}
return 0;
}
Why can one just print names[i] instead of *names[i]? Could someone provide a memory diagram for clarification?
Format specifier %s requires a parameter of type (char*), i.e. a pointer to an array of chars.
In char* names[], each element is such a pointer to an array of chars; after your initialisation, names[0] holds a memory address pointing to the begin of string literal "Zara Ali". Thus, it is correct to pass such a pointer as argument to printf("%s", ...).
However, if you write *names[0], then you actually dereference this pointer, yielding a char-value, which is in this case 'Z'. This is just as if you wrote printf("%s", 'Z'), such that expected data type char* and actual data type char do not match and yield compiler warnings and - when ignoring them -undefined behaviour.
I don't think a memory diagram is necessary.
Anything in c with * is a pointer in memory.
So,
int *a = 3;
a = 3;
*a = memory address
printf("result = %d, result 2 =%d\n", a, *a);
output:
result = 3, result 2 = 9023923 (this is a random memory address)
You must memorize this!
char is a single 8bit character, we represent strings in c by having an array of char's of unknown length are using the address of the first char, so for a single string we use
char * name
Meaning name contains the memory address (pointers) of the first character, we can get to the second char by just increamenting the memory address, name+1.
If we want an array of strings what we actually do is have and array of memory addresses (pointers) to multiple strings, So
char * names[] = ...
is an array of pointers to the first char of a string, you have to specify the number of elements in the c array but because you have supplied it with values, the compiler can infer the number of elements for you.
Each string you point to with each element in names can be located anywhere in memory, its just an array of memory addresses, names[0] could be equal to 10000 and names[1] could be equal to 10, meaning string 0 starts at address 10000 and string 1 starts at address 10, but because the way you have declared it the compiler will most likely have them in memory in order one after the other, but you could later on assign a different memory address to any one of the values.
names[2] = "New Values";
and the value of names[2] will then be the a different location in memory where "New Values" exists and the original string, "Nuha Ali", will still be located in memory at its original location untouched.
If you wanted you could created a char array like so
char names[] = "Zara Ali\0Hina Ali\0...
then names will be created long enough to contain the entire string and the string will be copied into the array instead of the first char memory addresses of each string being copied into the array. names will then just point to a single array of chars and names[1] will return you the second character, and you will not be able to determine where the strings end, any str function will assume the string terminates with the first '\0'.
(Note: your compiler may not let you actually put a string terminator '\0' mid string, I haven't tried it, though I think it should be legal if its not, but you get the idea of how the memory can be layout).
That is because the * is included in the [].
Have a look at Array subscripting:
The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))
While this question is a bit easy, I really dont know what is the exact explanation about this.
char *ptr = 'a';
I know a char is not a string but isn't that obvious to store 'a' in the first index of the pointer?
The assignment
char *ptr = 'a';
is equivalent to
char *ptr = 97; // This assumes ASCII encoding
While the assignment itself is valid, dereferencing this pointer is not valid.
If you would like to assign a pointer to point to something that has character 'a' in it, you could use a string literal, an array initializer, or take a pointer of a single-character:
char *ptr = "a"; // String literal
char a[] = {'a'}; // Character array
char *ptr = a;
char a = 'a'; // Single character
char *ptr = &a;
You can specify the address of a pointer. Basically it is a pointer to a pointer.
char* ptr = "a";
char** addrOfPtr = &ptr;
Note that storing the 'a' in the first index of the pointer isn't really what is going on here.
The 'a' is located somewhere in the computer's ram. The value stored in ptr is a number you can use to look up the ram location. It is known as an "address" because when people described these locations they made an analogy to home street addresses.
So 'a' is not stored in the first index of the address, any more than you are stored in the first index of your street address. You reside within the home at your street address, and the value for 'a' resides within the memory specified by the address value stored in ptr.
Note that this means the "pointer to a pointer", addrOfPtr, contains the address where the value within ptr resides.
---- Edit to drive the point home ----
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
char* ptr = "a";
char** ptr_ptr = &ptr;
printf("the value of ptr is '%s', and it is located at %p\n", ptr, &ptr);
printf("the value of ptr_ptr is '%p', and it is located at %p\n", ptr_ptr, &ptr_ptr);
return 0;
}
Will print out a pointer's value and address.
the value of ptr is 'a', and it is located at 0x7ffff79642d8
the value of ptr_ptr is '0x7ffff79642d8', and it is located at 0x7ffff79642d0
You can see that the value of ptr_ptr is the address of ptr, showing that a pointer stores the address of a value, in such a way that the syntax is designed to make it easier to get the value at that address than the actual stored address.
A pointer must have an address assigned to it. 'a' is not an address. It is a integer type with a value of 97, assuming ASCII. If you assign ptr the value 97 and try to dereference it you'll most likely get a segmentation fault because the address 97 does not exist.
char *ptr = "a"; is correct because the compiler will store the characters 'a' and \0' in contiguous memory, with the address of 'a' being stored into ptr.
#include <stdio.h>
#include <string.h>
int main()
{
char *p;
char str[10],name_first[10];
int i,count;
printf("\nName before reversing the string:::::::::::::");
scanf("%s",&name_first);
// I have taken a name in name_variable and now i want to reverse it
// using pointer for ex
count = strlen(name_first);
p=str+strlen(name_first)-1;
for(i=0;i<count;i++)
{
*(p-i)=*(name_first+i);
}
// now I am getting a reverse of string as a o/p but I want to know
// how p is pointing to the str as I'm not assigning any address,
// is it done automatically by the compiler?
printf("\nname after reversing the string::::::::::::::%s\n",str);
}
Actually you are assigning address to p in the following line of code.
p=str+strlen(name_first)-1;
str is an array so array name keeps the base address. Now adding the length of name_first array and subtracting 1 does the pointer arithmetic hence you are getting the result.
You have created a variable count = strlen(name_first).
So no need to call strlen again to assign the address to p.
For faster way , Just use
p=str+count-1;
The statement:
p=str+strlen(name_first)-1;
assigns to p an address within the memory pointed to by str.
So, let's say str starts at address 0x1000 and has a length of 10 and your name_first has a length of 5. Then p points to 0x1004.
When you loop runs, you are updating the characters in 0x1004, 0x1003, 0x1002, 0x1001 and 0x1000, thereby updating the contents of str.
Hope this clears your doubt.
str is the pointer of the first element of str[10]. In this statement: "p=str+strlen(name_first)-1;" rhs is an address
p, the pointer to a char, is assigned the address of the last char in the char array str in your p= line.
You then proceed to use that pointer to manipulate chars in that block of memory and them print out the manipulate memory content (because str is really just a pointer to the char array anyway).
I am practicing using pointers.
I have a pointer to an array of 3 strings: "dog", "cat", "rat".
I can print the contents using a for loop and using an array.
However, I am having problems printing them using pointer arithmetic. I would like to increment the pointer to the next element in the array. However, all it does is print the dog letters.
Code:
int main(int argc, char **argv)
{
char *str[3] = { "DOG", "CAT", "RAT"};
int i = 0;
/* display using an array element */
for(i = 0; i < 3; i++)
{
printf("str: %s\n", str[i]);
}
/* display using a pointer arthimatic */
while((*str)++)
{
printf("str: %s\n", str);
}
getchar();
return 0;
}
How can I accomplish this?
Edit:
Code:
while(str)
{
printf("str: %s\n", *(str++));
}
However, I get this error message. Doesn't the I-value have to be a variable of some sort?
error C2105: '++' needs l-value
You first have to get a pointer, and you would need a condition when to stop. A last NULL pointer can be used for that. So the code becomes
char *str[] = { "DOG", "CAT", "RAT", NULL };
char **elem_p = str;
/* display using a pointer arthimatic */
while(*elem_p) {
printf("str: %s\n", *elem_p);
elem_p++;
}
What you did was to increment the pointer stored in the array's first element. That pointer will never too soon equal to a null pointer (if at all), So, the loop will not stop until that pointers' internal value overflows or something else happens so that it equals to a null pointer. Then, you pass a pointer to the arrays first element to printf (you pass the array, but the compiler will convert it to a pointer - see below). Printf will interpret the bytes of those pointers as characters and print them, which will result in garbage printed out if it doesn't crash right away.
You want to increment at a higher level instead: Increment not one element (pointer) of the array, but the pointer to the elements itself. Now, you can't do
str++
Because str is an array. It's not a pointer, even though it can be converted to a pointer, which will then point to the first element of it. So, we create a pointer which points to str[0] initially, but increment it all again. Note that we increment it after printing, so that we print out the first element too.
Actually, i think i should explain why you can't do str++. Well, str is an array. An array is an object that occupies some fixed amount of storage. Above, the array occupies 4 times the size of a char pointer, 4 * sizeof(char*). What looks like a pointer at the first glance is a block of elements of the same type. For addressing elements, the compiler can make up a pointer out of an array in expressions, which then can be used to address elements in the array. If you do str++, the compiler will create a pointer for you. But that pointer is temporary, exists only for a short while for the sole purpose of immediately doing something with it, but it can not be changed like being incremented. That is the reason that we create a real pointer variable that we then can increment.
The problem with your code is that you're incrementing the dereferenced pointer str, which gives you a char * to the first element in the array (ie, dog).
You should be incrementing str itself, not what it points to.
However your loop termination check won't work in that case as there is no element in the array at the moment for which str == 0 holds true. In order to get that to work, you'll need to add a fourth element to the array that is 0.
str, being an array, cannot be incremented.
Right now, you're incrementing (*str), which is str[0]: the first element of that array. Since this element is a pointer, you're incrementing the pointer, making it reference the subsequent elements of the string "DOG".
What you need is a pointer that can point to (and thus walk over) str's elements. Since the elements are char*, the pointer to them would be char** - a double pointer.
(*str)++
Increments the value pointed to by s. You will need to increment the pointer itself and print the value of the pointee. Note, that str is not a l-value and you cannot increment it either.
Also, if you increment first, then you are left with only two legal strings that you can print. You invoke UB after that.
Try this:
int main(void)
{
/* we have added a sentinel to mark the end of the array */
char *str[] = { "DOG", "CAT", "RAT", 0 };
/* since str is an array, you cannot use it to loop, have a walker */
char **w = str;
/* display using a pointer arthimatic */
while(*w)
{
printf("str: %s\n", *w++);
}
return 0;
}
Look up operator precedence and binding in C.
while((*str)++)
{ printf("str: %s\n", str); }
This increments *str which is the letter 'd'. You don't want to do that. You want to increment the pointer. This code should do what you want:
while((str)++)
{ printf("str: %s\n", str); }