#include <iostream>
int main() {
int b = 3;
int* a;
*a = b;
std::cout << &a << a << *a;
}
When I execute a.out, Segmentation fault occurs
#include <iostream>
int main() {
int b = 3;
int* a;
*a = b;
std::cout << &a << a;
std::cout << *a;
}
While this code runs clearly with no error.
I'm pretty sure that max size of stdout buffer is bigger than couple of characters...
Why am I seeing Segmentation fault in same code with different new line?
Why am I seeing Segmentation fault ...?
Because the behaviour of the program is undefined. Here is the list of bugs in your programs:
*a = b;
^^
indirect through indeterminate pointer
std::cout << &a << a << *a;
^ ^^
| indirect through indeterminate pointer
read an indeterminate value
These bugs affect both example programs.
To fix the bugs, initialise a with a valid address of an int object.
Related
Is there any way to get a kernel to modify an integer via passing a pointer to that integer to the kernel? It seems the pointer is pointing to an address in device memory, so the kernel does not affect the host.
Here's a simplified example with the behavior I've noticed.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
__global__
void change_cuda(int* c);
void change_var(int* c);
int main() {
using namespace std;
int c = 0;
int* ptc = &c;
change_var(ptc); // *ptc = 123
cout << c << endl;
cudaError_t errors;
cudaMallocManaged((void**)&ptc, sizeof(int));
change_cuda<<<1, 1>>> (ptc); // *ptc = 555
errors = cudaDeviceSynchronize();
cudaFree(ptc);
cout << cudaGetErrorString(errors) << endl;
cout << c << endl;
return 0;
}
__global__
void change_cuda(int* c) {
*c = 555;
}
void change_var(int* c) {
*c = 123;
}
Ideally, this would modify c to be 555 at the end, but the output of this example is
123
no error
123
Clearly I am misunderstanding how this works. What is the correct way to get the behavior that I expect?
Yes, you have a misunderstanding. cudaMallocManaged is an allocator like, for example, malloc or new. It returns a pointer that points to a new allocation, of the size requested.
It is not some method to allow your host stack based variable to be accessed from device code.
However, the allocated area pointed to by the pointer returned by cudaMallocManaged can be accessed either from device code or host code. (It will not point to your c variable.)
You can minimally fix your code by making the following changes. 1. comment out the call to cudaFree. 2. print out the value of *ptc rather than c. Perhaps a more sensible change might be like this:
int main() {
using namespace std;
int* ptc;
cudaMallocManaged((void**)&ptc, sizeof(int));
change_var(ptc); // *ptc = 123
cout << *ptc << endl;
cudaError_t errors;
change_cuda<<<1, 1>>> (ptc); // *ptc = 555
cudaDeviceSynchronize();
errors = cudaGetLastError();
cout << cudaGetErrorString(errors) << endl;
cout << *ptc << endl;
return 0;
}
#include <iostream>
int main() {
int a[2][2] = {{1,2}, {3,4}};
int *c = *a;
int **b = &c;
std::cout << **(a+1); // outputs 3
std::cout << **(b+1); // segmentation fault
}
Why does one cout results in segmentation fault and other doesn't? Shouldn't they be referring to the same value?
Lets start with
int *c;
Actually what comes before is not that relevant, because c is just a pointer and then here
int **b = &c;
you store the address of c in b. The address of c has nothing to do with what value is stored in c. c is just a pointer, taking its adress doesn't let you magically access a 2d array.
cout << **(b+1); // segmentation fault
Already b+1 is undefined behaviour. Dereferencing that pointer cannot give you something meaningful.
PS: tbh I cannot tell you how to use the double pointers correctly here. Once I started to learn c++ I unlearned anything I knew about working with arrays via pointers. Use std::vector or std::array and save yourself some headaces.
In this statement
cout << **(b+1);
the expression b+1 points outside the array (that is more precisely outside the object c). You should write
cout << *( *b + 2 );
The dereferenced pointer b points to the pointer to the first element of the two-dimensional array. When adding to it the number of elements in the array of the type int[2] you will get the pointer to the first element of the second "row" of the two-dimensional array. Now you need again to dereference it to output the pointed value.
I rewrote the code to highlight what is happening, as below:
#include <iostream>
int main() {
int a[2][2] = {{1,2}, {3,4}};
int *c[2] = {a[0], a[1]};
int **b = c;
std::cout << **(a ) << ','; // outputs 1
std::cout << **(b ) << ";\n"; // outputs 1
std::cout << **(a+1) << ','; // outputs 3
std::cout << **(b+1) << ";\n"; // outputs 3
}
LINK: https://ideone.com/ixj3NV
UPDATED LINK: https://ideone.com/g7jjVN
(Clarified the original source to extend the program)
I am trying to cout the address of the variable abc and the program just crash
int main()
{
int *app;
int abc = 2;
*app=3;
cout << *app << endl << &*app << endl << abc;
cout << &abc;
}
However, if I remove the address variable int *app , then it will cout the address of abc
int main()
{
int abc = 2;
cout << &abc;
}
I have no idea why would the existence of another unrelated address variable would affect it. Please advise.
The problem lies here:
*app=3;
this will probably cause a Segmentation Fault, Undefined Behavior.
If you remove it, it makes sense to see the expected output.
What are you trying to do?? This is undefined behavior.
int *app; // pointer is not initialized.
int abc = 2;
*app=3; // de-referencing an uninitialized pointer. Bad.
I have the following code:
#include <iostream>
using namespace std;
int main ()
{
int myvar = 5;
int * p;
cout << "Hello2" << endl;
*p = myvar;
cout << "Hello" << endl;
cout << p << endl;
//cout << &myvar << endl;
}
I know I am not doing the right thing by not initializing the pointer. I was just playing with pointers and noticed this. The issue is when I comment out the last line, the program executes normally. But as soon as I uncomment the line, I get a segmentation fault. I don't know why printing address of myvar is causing this? Has myvar been modified in any way because of pointer dereferencing? I am using C++11.
int* p;
*p = myvar;
You are creating an uninitialized pointer and then derferencing that pointer. This has undefined behavior because p has to point to something for it to be derferenced correctly. Therefore your program's behavior can't be reasoned with.
Segmentation Fault occurs when trying to access a virtual memory address that has no read permissions.
In your case, the local variable p holds uninitialized garbage from the stack.
you are dereferencing a memory address that might not be readable(e.g no read permissions, hence the segmentation fault when trying to access it).
I'm not entirely sure the purpose of your snippet, but the following code will work, and perhaps it will help:
int myvar = 5;
int *p = nullptr;
p = &myvar;
cout << myvar << endl;
cout << &myvar << endl;
cout << p << endl;
cout << *p << endl;
(Note: I used two lines for setting 'p' because that is how you did it in your snippet. You could easily just use: int *p = &myvar; )
Anyway, there are scope issues here as p will only be valid as long as myvar is in scope; however, this does illustrate the basics of pointers. myvar and *p will return the same value (the value being pointed to), and &myvar and p will return the same value (the location of value in memory.)
Why does the following code print 0? i.e. why does variable a is located right after variable d, even though pointer variable c is being declared between them?
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = &d - c;
int &f = e;
e ++;
cout << e << " " << endl;
return 0;
}
Working backwards:
e ++;
cout << e << " " << endl;
If this prints 0, then the value of e before executing this code must have been -1.
int e = &d - c;
So the result of the above address subtraction must have been -1.
unsigned int a /* = whatever, the value of a doesn't matter */;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d /* = whatever, the value of d doesn't matter */;
b is a reference to a, so &b is equivalent to &a.
So &d - c is equivalent to &d - &a, and that subtraction yields -1.
Conclusion: the address of d is sizeof (unsigned int) bytes after the address of a. (Pointer subtraction is scaled by the size of the pointed-to type.)
Probably.
In fact, the behavior of subtracting pointers to two independently defined objects is undefined. The standard says literally nothing about what it should do.
In practice, a compiler will probably generate the simplest possible code for a pointer subtraction, and that simple code will probably treat unrelated pointers as if they were comparable, even though the language doesn't say they are.
It's likely, given your program's output, that b and d happen to be allocated next to each other. Nothing says that declared variables have to be allocated in the order in which you declare them. If you want objects to be allocated in memory in a define order, put them into a struct or make them elements of an array.
It's also likely that the same program will yield different results if you run it on a different system, or on the same system with a different compiler, or on the same system with the same compiler with different compiler options. In principle, it could even behave differently with everything the same but during a different phase of the moon.
And a compiler is permitted to assume that your code's behavior is well defined, and perform transformations that are valid only given that assumption. In effect, by subtracting two unrelated pointers, you have promised the compiler that they both point to elements of the same array object or just past the end of it (where a single object is treated as a 1-element array) (or that both are null pointers; that's one difference between C and C++). You have lied to the compiler, which means it is under no further obligation to you.
Don't do that.
Unless you explicitly place objects using your own memory management system, their relative positions in memory will be compiler- and system-dependent.
your line int e = &d - c; is substracting 2 unsigned int *.
In memory, &d is 8 bytes farther then c (it depend on your system, but we suppose that an int is 4 bytes). Effectively, you construct your stack in this way :
unsigned int a = 100; // &a is 0x0
unsigned int &b = a; // &b is 0x0 (it's just an alias)
unsigned int *c = &b; // &c is 0x4
unsigned int d = (unsigned int)(c); // &d is 0x8
An unsigned int use 4 bytes in memory.
So, when your are doing &d - c, it must return 2, because your are using pointer arithmetics with unsigned int* (4*2=8);
You can try with int e = (short*)&d - (short*)c result should be 4 because short size is 2 (2*4=8).
You can try with int e = (char*)&d - (char*)c result should be 8 because char size is 1 (1*8=8).
Try to print your variables and addresses to understand :
#include<iostream>
using namespace std;
int main () {
unsigned int a = 100;
unsigned int &b = a;
unsigned int *c = &b;
unsigned int d = (unsigned int)(c);
int e = (short*)&d - (short*)c;
//int &f = e;
//e ++;
cout << "&a: " << (unsigned int)&a << endl;
cout << "&b: " << (unsigned int)&b << endl;
cout << "&c: " << (unsigned int)&c << endl;
cout << "&d: " << (unsigned int)&d << endl;
cout << endl;
cout << " a: " << a << endl;
cout << " b: " << b << endl;
cout << " c: " << (unsigned int)c << endl;
cout << " d: " << d << endl;
cout << endl;
cout << " e: " << e << endl;
return 0;
}
Here, with int e = (short*)&d - (short*)c;, result is :
&a: 3220197356
&b: 3220197356
&c: 3220197360
&d: 3220197364
a: 100
b: 100
c: 3220197356
d: 3220197356
e: 4