I was messing around trying to understand pointers and the operator "new"
and I ended up getting even more confused on what these 2 codes should result to, which is other but its not, so I wanted to understand what happened here.
thanks in advance.
#include <iostream>
using namespace std;
int main()
{
int * p = new int(50);
p[1] = 33;
cout << *p << endl;
}
Output: 50
and when I tried this
#include <iostream>
using namespace std;
int main()
{
int * p = new int[50];
p[1] = 33;
cout << *p << endl;
}
Output: -842150451
I was wondering about the meaning of each result.
In the first case
int * p = new int(50); // allocates 1 int on heap, initialized to value of 50
p[ 1] = 33; // p gives you the address of integer,
// p[1] moves the p pointer forward and accessing
// the pointed object results in undefined behavior,
// this means that at this moment anything can happen
// exception, crash, home war, nothing, everything,
// printing garbage value as well
In the second case:
int* p = new int[50]; // allocates 50 ints on heap, uninitialized
p[ 1] = 17; // initializes element with index 1 to value of 17
std::cout << *p; // p gives you the address of first element, with index 0
// which is still uninitialized, thus prints garbages
You should use
int* p = new int[50]();
to value-initialize ints to 0.
In the first one, you created dynamically a single int with a value of 50. When you try to assign the value 33, you actually assign it in memory that is not yours. It is undefined behaviour. But when you print it, you print the original value you made, which was 50.
In the second one, you created dynamically an array of 50 int. You've then specified the second value of in the array should be 33.* So when you print the value with cout << *p << endl;, you end up printing only the first value, which is undefined. Try it again, you'll probably get another value.
*Edit: as pointed in the comments, I should have been more explicit about this. An array starts at 0. So if you want to access the first value p[0] would do it.
In the first case you're creating an array of 50 ints, assigning a value to the SECOND int in the array, and then printing the first element in the array. Array indices start at 0, so when you dereference the pointer in your cout statement, it's printing whatever happened to be in memory at index 0.
In the second case you're creating a single integer, and initializing it with the value 50. When you dereference the pointer in the print statement, you're getting the integer you just created. The p[1] = 33 may or may not cause an error as your accessing unassigned memory.
int* p = new int[50];
allocates an array of int on the heap with 50 uninitialized elements, ranging from index 0 to 49.
Setting p[1] to 33 doesn't change p[0] which is what you're printing with "cout << *p".
The value -842150451 (0xCDCDCDCD in hex) is a magic number "Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory", see this question on SO.
int* p = new int(50);
allocates exactly one int on the heap and initializes it with the value 50, so setting p[1] afterwards should result in undefined behavior since you didn't allocate that memory where p[1] is referring to.
I'd recommend to use the Visual Studio Memory Windows to see what happens to the memory you're allocating while stepping through your code.
Related
Recently, I begin to learn C++ language for Pointer series, I knew the pointer is the specific var what is used to hold the address of another variable. And when we change the value at the memory area which the pointer is hold, it also change the value of that var. So then i just wrote the code to do it.
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main(int argc, char const *argv[])
{
int n=5;
int *p=&n; //pointer p hold the address of n
std::cout<<"value of n = "<<n<<endl;
std::cout<<"value of n = "<<*p<<endl;
std::cout<<"value of n= "<<*(&n)<<endl;
std::cout<<"the address of n = "<<&n<<endl;
std::cout<<"the address of n = "<<p<<endl;
*p=19; //change the value at the address of n -> mean n definitely change
std::cout<<"value of n once *p changed = "<<n<<endl;
p++; //p address increase 4 bytes
std::cout<<"address of p changed = "<<p<<endl;
(*p)++;
std::cout<<"address of p = "<<p<<endl;
return 0;
}
then i got the resul below :
As I mark red in my picture, when I do (*p)++ - I understood that the value at the address p hold will increase 1, but once I check the result, it didn't show the value of p after (*p)++ line , just the address of p has increased 1 byte.
What is the reason for this?
If we break down your code into the important parts, we see:
int n=5; // 1.
int *p = &n; // 2.
p++; // 3.
(*p)++; // 4. Dereference and increment.
You clearly have a good grip on what 1-3 do in this code. But, 4 is a big problem. In 3, you changed the pointer. The pointer previously pointed to n, after incrementing, what does it point to now?Wherever it is, it is not necessarily memory that we own and can actively change.
In line 4, you change it. This is undefined behaviour which, from the linked page you can see:
undefined behavior - there are no restrictions on the behavior of the program.
So the program can do pretty much anything.
Your program has undefined behavior.
Let's look at this sequence picked from your program:
int n=5;
int *p=&n;
p++; // p now points to some unknown memory area
(*p)++; // here you dereference `p` - undefined behavior.
You are never allowed to dereference a pointer that is not pointing to an object that is "alive".
I'm just playing around pre/post increment/decrement in C language. In the program below, everything works fine with variable var. But increments to the pointer variable *varAddress++ return garbage value.
#include <stdio.h>
int main(int argc, const char * argv[])
{
int var = 1;
int *varAddress = &var;
printf("Value befor pre increment %d\n",*varAddress);
++*varAddress;
printf("Value after pre increment %d\n",*varAddress);
printf("Value befor post increment %d\n",*varAddress);
*varAddress++;
printf("Value after post increment %d\n",*varAddress);
return 0;
}
Output
Value befor pre increment 1
Value after pre increment 2
Value befor post increment 2
Value after post increment 1606416400
Program ended with exit code: 0
According to the Operator Precedence, suffix increment has higher precedence than indirection operator, so *varAddress++ is equivalent as:
*(varAddress++);
which will increase the pointer itself, then point to memory unallocated somewhere else, that's why *varAddress will return garbage value (this is UB).
You might want:
(*varAddress)++;
++ has higher precedence than * so by doing *varAddress++ you are moving a pointer to some un-owned location and trying to dereference it, which will lead to undefined behavior.
#include<stdio.h>
void main(){
char arr[] ="abcd";
char *p=arr,*q=arr;
char k,temp;
temp = *p++; /* here first it assigns value present in address which
is hold by p and then p points to next address.*/
k = ++*q;/*here increments the value present in address which is
hold by q and assigns to k and also stores the incremented value in the same
address location. that why *q will get 'h'.*/
printf("k is %c\n",k); //output: k is h
printf("temp is %c\n",temp);//output: temp is g
printf("*p is %c\n",*p);//output: *p is e
printf("*q is %c",*q);//output: *q is h
}
Since the number of elements is determined by some conditions, I wrote a program like this;
int i = 0;
int *layer;
while (i != 12){
layer = new int;
layer[i] = i;
cout << layer[i] << endl;
i++;
}
delete[] layer;
return 0;
I get the result;
0
1
2
3
4
5
6
And then program crashes. What is the reason of this and how should I modify the program in order to allocate memory for unknown number of elements?
Thanks in advance!
You have undefined behaviour. You allocate space for a single int, then you treat it as an array.
layer = new int; // single int
layer[i] = i; // wat??
Then you leak the memory, then you call delete[] on the last newed int. Since it isn't clear what you want to do with your code, I can only offer some suggestions:
Consider using std::vector<int> as a dynamic array. It will save you a lot of trouble.
If you must allocate an array with new (you probably don't), you need new int[n] where n is the number of elements.
Call delete [] for every new[] and delete for every new.
EDIT: Thanks a lot for the answers. That's right, I will try using vectors instead.
I have a program where I dynamically allocate memory.
The class has an attribute which is an array of structs (**) and also an array of pointers (*) which point to each element of the array of structs, so I make 2 Mallocs. The struct is called "context".
The realloc works fine and doesn't return NULL, but as soon as I have more than 2 elements, the program will give me a segfault when trying to save a value in an element of the array. How can I prevent this segfault?
int my_class::method(uint32_t struct_element)
{
int i= this->numofcontexts;
if(this->local_context_array == NULL)
// That means it is empty and we have to make our first malloc
{
this->local_context_array = (context_t**) malloc(sizeof(context_t*));
*(this->local_context_array) = (context_t*) malloc(sizeof(context_t));
i++;
std::cout << "\n1 Malloc was made of size " << sizeof(context_t)<<"\n";
}
else
// Array is not empty and we have to use realloc
{
this->local_context_array = (context_t**) realloc(this->local_context_array, (i+1)*sizeof(context_t*));
*(this->local_context_array) = (context_t*) realloc(*(this->local_context_array), (i+1)*(sizeof(context_t)));
std::cout << "\n1 Realloc was made of size " << (i+1)*(sizeof(context_t)) <<"\n";
i++;
std::cout << "\nWe now have " << i <<" elements\n";
// As soon as the array is bigger than 2 elements, this gives segmentation fault:
//(this->local_context_array[i-1])->struct_element = struct_element;
}
From the code posted and the symptoms you describe, it seems you do not do this at the end:
this->numofcontexts = i;
If this is true, then every time you call this method, it will find numofcontexts == 0 and local_context_array not NULL, so it will move to your else clause, when it will reallocate the array to i+1 (always 1).
First call will succeed, second call will also succeed with array size of 1 element, and if you try to assign to elements over [0] at this point, you may get a segfault. The reason you might not get a segfault at [1] is usually related to some other variable occupying the space and being trashed but which does not always generate a segfault immediately.
"header" is an object of a struct and you can consider header.img to have a value of 496. And header struct has 3 integer elements so is the value 12 bytes. (Considering 4 bytes a int)
double** MatrixBuffers = new double* [header.img];
MatrixBuffers[0] = new double[header.img* 12];
for (unsigned int i=1; i<header.img; ++i) {
MatrixBuffers[i] = MatrixBuffers[0] + i * 12;
}
globaldata.adv_MatrixBuffers = MatrixBuffers;
I understand that MatrixBuffers is a pointer to 496 doubles. But I don't understand what's happening in the second line.
MatrixBuffers[0] = new double[header.img* 12];
1.Does this mean MatrixBuffers[0] is a pointer to 496*12 doubles ?
2.What is happening in the for loop ?
3.Later in the code, MatrixBuffer[0] is being passed to a function. Does this mean I am passing a pointer that is the base address to MatrixBuffers[0] ?
For a double pointer you have to allocate memory for first as well as second dimension.
For the second level instead of allocating memory for every dimension he allocates memory at one shot
MatrixBuffers[0] = new double[header.img* 12];
Inside the for loop they move the address and assign the same to every index.
Instead he can also do like this inside the for loop and comment the line above the for loop
MatrixBuffers[i] = new double[header.img];