This question already has answers here:
difference between pointer to an array and pointer to the first element of an array
(6 answers)
What is array to pointer decay?
(11 answers)
Closed 4 years ago.
I was trying to learn pointer to an array , but I'm not able to understand as to why *ptr and ptr print the same value
/*Here is the source code.*/
#include<stdio.h>
int main()
{
int arr[] = { 3, 5, 6, 7, 9 };
int *p = arr;
int (*ptr)[5] = &arr;
printf("p = %u, ptr = %u\n", p, ptr);
printf("*p = %d, *ptr = %d\n", *p, *ptr);
return 0;
}
and here is a snapshot of the output I got:
Change the way you print to this:
printf("p = %p, ptr = %p\n", (void*)p, (void*)ptr);
printf("*p = %d, *ptr = %p\n", *p, (void*)*ptr);
since the format specifier p is used to print a pointer. Moreover, the pointer should be casted into a void pointer, when you intend to print it.
Possible output:
p = 0x7ffed5b62fd0, ptr = 0x7ffed5b62fd0
*p = 3, *ptr = 0x7ffed5b62fd0
where now you see that they are the same.
Related
So can someone explain what would happen if I pass ...*p as the argument name for the foo function
int main()
{
int i = 10;
int *const p = &i;
foo(&p);
printf("%d\n", *p);
}
void foo(int **p)
{
int j = 11;
*p = &j;
printf("%d\n", **p);
}
Don't do that. You'll have a pointer to an undefined memory location on the stack. Any other function call between foo(&p); and printf("%d\n", *p); is bound to overwrite that memory location with new data.
Let's look at a simple example here! We have a function print_address, which takes an address and prints it. We're gonna print the address of an int, as well as the address of a pointer to that int, and a pointer of a pointer to that int.
#include <stdio.h>
void print_address(void* addr) {
printf("Address: %p\n", addr);
}
int main()
{
int value = 0;
int* value_ptr = &value;
int** value_ptr_ptr = &value_ptr;
print_address(&value);
print_address(&value_ptr);
print_address(&value_ptr_ptr);
return 0;
}
When I run this code, I get the following output:
Address: 0x7fffa4936fec
Address: 0x7fffa4936ff0
Address: 0x7fffa4936ff8
The first address is to value, the second address is to value_ptr, and the third address is to value_ptr_ptr. Each address is a little higher than the previous one, because each variable has been stored a little higher up on the stack.
The same thing happens with function calls. When we call a function, the memory for all the local variables in that function is stored a little higher up on the stack then the memory for all the local variables in the current function:
#include <stdio.h>
void print_address(void* addr) {
printf("Address: %p\n", addr);
}
void f3(int*** ptr) {
print_address(ptr);
}
void f2(int** ptr) {
print_address(ptr);
f3(&ptr);
}
void f1(int* ptr) {
print_address(ptr);
f2(&ptr);
}
int main()
{
int value = 0;
f1(&value);
return 0;
}
This time when I ran it, the output was
Address: 0x7ffeca71dc2c
Address: 0x7ffeca71dc08
Address: 0x7ffeca71dbe8
If you notice, the gaps between addresses are higher, but that's because of the extra stack space it takes to do a function call.
j is destoyed after exiting foo, so doing anything with it after foo calling in main is incorrect, until you reset it on another object (I mean printf("%d\n", *p)).
Well, what you're doing is passing pointer on pointer on integer.
As you could see, pointers are often used to pass arrays:
void print_array(int* a, int n) {
for (int i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
}
And pointers on pointers are used to pass two-dimensional arrays, for example in int main(int argc, char** argv) { ... } argv is array of strings or array of arrays of char-s.
You can't pass *p, but let's say you could...
It looks like you are trying to get your function to update a parent variable - and passing &p is the correct way to do it. But you are adding one too many dereference. I highly recommend you read this: https://boredzo.org/pointers/
// Let's assume you only have 4 memory locations for variables: 1 2 3 and 4.
// let's call these m[1] m[2] m[3] and m[4]
// i is at 1, p is at 2, j is at 3, and the p inside the function is at 4.
// let's call that second p, q rather
// so you have: m[1..4] = { i, p, j, q }
// now execute the code in your head:
int main()
{
int i = 10; // m[1] = 10
int *const p = &i; // m[2] = 1
foo(&p); // foo(2)
printf("%d\n", *p); // printf m[2]
}
void foo(int **q) // q = m[m[2]] = m[1] = 10
{
int j = 11; // m[3] = 11
*q = &j; // m[10] = 3 // segfault!
printf("%d\n", **q); // printf m[m[10]] = m[3] = 11 // if it didnt' segfault
}
It looks like this is what you are trying to do:
#include <stdio.h>
void b(int *q,int n) {
*q=n;
}
int main() {
int i=123;
int *p=&i; // *p and i are now synonymous
printf("%i ",i);
printf("%i ",*p); // same thing
b(p,111);
printf("%i ",i);
b(&i,111);a // same thing
printf("%i ",i);
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
EDIT (Remake): Here's what I'm trying to do:
char* someArray = new char[someIntVariable];
And then loop over the array and use a custom function to get the contents of the other array (that's where the problem lies):
char* temp = someFunc(someArray, someIntVariable); //someFunc is a char* returning function
for(int i = 0; i < someIntVariable; i++){
someArray[i] = temp[i] //temp[i] is where the problem lies. It returns something like: /213
}
Text version: I'm trying to get a pointer to a char array to return all of the arrays contents (only using one single pointer) and loop over a previously created array and fill it's spaces or somehow assign it one single assignment.
Hope this is comprehensible.
"someFunc":
char* convertCharArr(char* _inputArr, int arrSize){
char *inputArr = new char[arrSize];
std::memmove(inputArr, _inputArr, sizeof(*inputArr));
static char *resizedUsrInptAns = new char[arrSize];
for(int i = 0; i < sizeof(inputArr)/sizeof(inputArr[0]); i++){
if(i == arrSize + 1){
break;
}
resizedUsrInptAns[i] = inputArr[i];
}
return resizedUsrInptAns;
}
ptr2 and ptr1 are equivalent, so I am going to ignore ptr2 for my answer.
If you want to clone a char array of unknown size, you have to use dynamic memory allocation:
char * p = malloc(strlen(ptr1) + 1);
strcpy(p, ptr1);
// ...
free(p);
You can't assign a pointer to an array, thats impossible in c. You can only do the opposite, assigning an array to a pointer.
You will have to create a new array(with dynamic allocation) and copy the data into that array.
Example
char* pChar = GetArrayPointer();
char* pNewArrayPointer = (char*)malloc(strlen(pChar) + 1);
strcpy(pNewArrayPointer, pChar);
Edit
1) You don't have to copy _inputArr because you don't write data to it in converCharArr().
2) Why are you using sizeof(inputArr)/sizeof(inputArr[0]), it doesn't works, because inputArr is a pointer(well, there are some differences between pointers and arrays :)). You should use arrSize.
Array and pointer differences : http://www.geeksforgeeks.org/g-fact-5/
In your example both prt1 as well as ptr2 are pointing to same char. And you can get same effects for ptr1/ptr2 using cout what you get for arr1.
So, below all will print same thing:-
cout << arr1;
cout << ptr1;
cout << ptr2;
If you want to create new array using ptr2 with same contents as of arr1, then
ptr2 = malloc(strlen(ptr1) + 1);
strcpy(ptr2, ptr1);
May this would help
link: http://ideone.com/Nwqd22
#include <iostream>
using namespace std;
char* fun(){
char * returnValue = "String";
return returnValue;
}
int main() {
char * firstVariable;
firstVariable = fun();
cout << firstVariable;
return 0;
}
I've got an argument with my co-workers.
Once I did try to modify constant reference.
Sample of code is below:
#include <cstdio>
#include <cstdlib>
using namespace std;
int main(int argc, char const *argv[])
{
const int* A = NULL;
printf("A = %p\n", A);
int** pA = const_cast<int**>(&A);
*pA = new int(5);
if (pA != NULL)
printf("pA = %p, value = %d\n", pA, *pA);
else
printf("pA null pointer\n");
if (A != NULL)
printf("A = %p, value = %d\n", A, *A);
else
printf("A null pointer\n");
return 0;
}
Everything works fine and the log is
A = 00000000
pA = 0028FED8, value = 4068760
A = 003E1598, value = 5
I think it works that way:
I create a const pointer variable A with '0' (zero) value is stack. It is local variable wich occupies 4 bytes of memory in stack.
then I create a pointer to pointer variable, I cast away constant modification and take address of the variable
I think this code works fine and will not lead to a bug. But I need some kind of explanations. Am I right?
const int *a and int * const a are different.
Case 1
[const is used on *a]
Here the value of a is constant. The address pointed by a can be changed.
const int *a = malloc(sizeof (int));
if (a)
{
//*a = 10; //not allowed
a = malloc(sizeof (int));; //allowed
}
Case 2
[const is used on a]
Here the address of a is constant. The value of a can be changed.
int * const a = malloc(sizeof (int));
if (a)
{
*a = 10; //allowed
//a = malloc(sizeof (int));; //not allowed
}
EDIT:
As suggested by #lifeOfPI, read about using const_cast .
Can I print a pointer in an OpenCL function?
I can use printf in kernel functions however I can't find the way to print a pointer.
Is there some equivalent to the following?:
int *ptr = 5;
printf("%p \n", (void *)ptr);
What is wrong with this?
int x = 5;
int *ptr;
ptr = &x;
printf("%p \n", ptr);
You can't make ptr point to 5. Pointers must point to memory on:
The stack: int x
or
the heap: int* ptr = new int(5)
I realize that my example not correct in general. But interesting to find out how it works.
/* C/C++ (gcc-4.3.4) */
#include <stdio.h>
int main() {
/*volatile*/ int i = 5;
int j = 500;
int *p = &j;
printf( "%d %x\n", *p, p );
p++;
printf( "%d %x\n", *p, p ); // works correct with volatile (*p is 5)
//printf( "%d %x\n", *p, &i ); // works correct without volatile
return 0;
}
Is it some kind of optimization?
UPDT
Ok i got about UB. I won't hope on another else.
BUT if i have 2 int vars which placed adjacent to each others (see addresses) why this code shouldn't works?
p++;
The code has undefined behavior. Pointer is pointing to some garbage location. Dereferencing it leads to unpredicted results.
What do you call corerct?
It isn't guaranted, how variables will be stored, so ANY result is correct
Both variables are not necessarly adjacent in memory. You could use an array to do this.
#define PRINT(p) (printf("%i %p\n", *(p), (void *)(p)))
int t[2];
int *a = &t[0];
int *b = &t[1];
*a = 5;
*b = 6;
int *p = a;
PRINT(p);
++p;
PRINT(p);