strange C++ variable initialization - c++11

I know this is a basic topic. But I run into a very strange case.
Here are two versions of my code:
Version 1:
int num;
char *ptr;
std::cout << (num == 0) << std::endl;
std::cout << (ptr == nullptr) << std::endl;
Output:
1
0
Version 2:
int num;
char *ptr = nullptr;
std::cout << (num == 0) << std::endl;
std::cout << (ptr == nullptr) << std::endl;
Output:
0
1
It seems the initial value of the integer num depends on the initialization of the pointer ptr.
Could anyone please explain this? I read some other post but still don't understand. I tried to compile and run many times. The value doesn't seem to be random. It's always this result.
I'm using g++ init.cc -o out -std=c++11
Thanks in advance!

Your program causes undefined behaviour by using the value of an uninitialized variable. As explained by the link, that means anything at all can happen and the output is meaningless. You should not waste time trying to understand the output; instead, fix the program.

First of all, nullptr is not equal to 0. If you remove the code (ptr == nullptr) from std::cout and just initialize the ptr as nullptr and print ptr then you will see that nothing is printed.

Related

Why conditional breakpoints don't work in VScode with the hit count condition?

I put a conditional breakpoint in this code on the line std::cout << i << ", "; :
(I use gdb)
#include <iostream>
int main() {
for (int i = 0; i < 10; ++i) {
std::cout << i << ", ";
}
std::cout << std::endl;
}
I set the hit count on 4. But I see VScode break on the breakpoint the very first time it gets to the breakpoint.
Anyone knows how to fix this ?
Oddly enough, if I enter the expression i == 4 it works tho.
Thx!

C ++ , My for loop doesn't work when I run it on the terminal. Any ideas?

When I run it on the terminal it works fine but the loop. The for loop just doesn't do anything at all. I'm learning C++, so I don't know much.
#include <iostream>
#include <cstring>
using namespace std;
int main( int argc, char *argv[] ) {
if (argc == 2) {
cout << "The first argument is " << argv[0] << endl;
cout << "The second argument is " << argv[1] << endl;
} else if (argc > 2) {
cout << "Too many arguments" << endl;
exit(0);
} else {
cout << "Only one argument" << endl;
cout << "The argument is " << argv[0] << endl;
exit(0);
}
if (atoi(argv[1]) < 0) {
cout << "Error negative number" << endl;
exit(0);
}
// this loop does not work, everything else does.
for (int i = 1; i >= atoi(argv[1]); i++){
int count = atoi(argv[1]--);
cout << count << endl;
int sum = sum + i;
}
cout << "The sum is: " << endl;
return(0);}
I think that could be the if statements what are messing around with the loop.
I think you made mistake in the for loop.
You show use "<=" instead of ">=" in the for loop.
Hope this might helps you.
I guess your code is not reaching the for loop as you have exit() conditions on each and every condition of if. Your code only reaches the loop if you are passing 2 arguments in the terminal while you are running your code

Segmentation fault (Core Dumped) C++ Beginner

So, I am new to C++. I've researched Segmentation Fault (core dumped), memory allocation, and new/delete although I am having trouble understanding the concepts. I do believe my problem lies with memory allocation though and that's why I thought "delete" would have solved my problem. May someone please push me in the right direction?
Input
#include <iostream>
#include <string>
using namespace std;
struct CandyBar
{
string name;
double weight;
int calories;
} ;
int main()
{
CandyBar* backpack = new CandyBar[3];
backpack[0] = {"Choco Chalk", 5.1, 725};
backpack[1] = {"Twisty String", 1.8, 300};
backpack[2] = {"Gummy Nums", 4.4, 475};
cout << "Name\t\tWeight\tCalories" << endl << endl;
for (int x = 0; x < 4; x++)
{
cout << backpack[x].name << "\t" << backpack[x].weight << "\t" << backpack[x].calories << endl;
}
delete backpack;
return 0;
}
Output
Name Weight Calories
Choco Chalk 5.1 725
Twisty String 1.8 300
Gummy Nums 4.4 475
(Segmentation fault) core dumped
I see two bugs:
Your loop for (x = 0; x < 4; x++) will iterate through x values 0, 1, 2, 3. However, since you allocated backpack with new Candybar[3], backpack points to only enough memory to hold 3 CandyBars, namely backpack[0], backpack[1], backpack[2]. As it stands, on its fourth time through, your loop will attempt to access backpack[3], which is off the end of the array.
When you allocate memory with new[] (as you did since you allocated an array of CandyBar), you have to deallocate it with delete[], not just plain delete. See delete vs delete[] operators in C++.
When I changed your loop exit condition to x < 3 and your deallocation to delete[] backpack;, the program worked for me.

Address of an instance emplaced to std::vector is invalid

I have 2 std::vectors:
to first vector, I emplace instance
to second vector, I want to store the address of the instance just emplaced
But it does not work, i.e., the stored address differs from the emplaced instance's address.
If it matters at all, I'm on Linux and using g++ 5.1 and clang 3.6 with -std=c++11.
Here's a working example to illustrate the problem.
#include <iostream>
#include <vector>
struct Foo {
Foo(int a1, int a2) : f1(a1), f2(a2) {}
int f1;
int f2;
};
int main(int, char**) {
std::vector<Foo> vec1;
std::vector<Foo*> vec2;
int num = 10;
for (int i = 0; i < num; ++i) {
vec1.emplace_back(i, i * i);
// I want to store the address of *emplaced* instance...
vec2.push_back(&vec1.back());
}
// same
std::cout << "size 1: " << vec1.size() << std::endl;
std::cout << "size 2: " << vec2.size() << std::endl;
// same for me
std::cout << "back 1: " << &vec1.back() << std::endl;
std::cout << "back 2: " << vec2.back() << std::endl;
// typically differ ?
std::cout << "front 1: " << &vec1.front() << std::endl;
std::cout << "front 2: " << vec2.front() << std::endl;
for (int i = 0; i < num; ++i) {
std::cout << i + 1 << "th" << std::endl;
// same for last several (size % 4) for me
std::cout << "1: " << &vec1[i] << std::endl;
std::cout << "2: " << vec2[i] << std::endl;
}
}
Questions
Is it correct behavior ? I guess it's caused by storing the address of temporary instance but I want to know whether it's permitted by the standard (just curious).
If above is true, how to work around this ? I resolved this by changing first one to vector<unique_ptr<Foo>> but is there any idiomatic way ?
Two options:
1) You can simply fix your test. You just need in you test preallocate enough memory first with
vec1.reserve(10);
Well, this is implementation details for std::vector. As more and more items are added to std::vector it needs to get more space for them. And this space must be contigious. So when there is not enough space for a new element std::vector allocates a bigger block of memory, copies existing elements to it, add the new element and finally frees the block of memory that it used before. As a result addresses that you stored in vec2 might become invalid.
However, if you preallocate enough memory for 10 elements then you code is correct.
Or, since reserving memory is sort of tricky thing to do
2) use std::deque since insertion and deletion at either end of a deque never invalidates pointers or references to the rest of the elements (http://en.cppreference.com/w/cpp/container/deque) and forget about the problem with invalidated addresses. So no need to reserve memory.

how does the below code output 3? (how does the below code read?)

The specific part I do not understand is how the -a in the if statement changes -3 to 3. Can someone explain how the -a changes a = -3 to a = 3?
#include <iostream>
int main(){
signed a = -3;
if (a < 0){ std::cout << -a << std::endl; }
else { std::cout << a << std::endl; }
system("pause");
return 0;
}
It's an example of unary negative, when a=-3 (which is less than 0, the code then enters the if block) then -a is -(-3) which is 3.
This code won't change the value of 'a' at all. It will remain 3 (a=3) even after execution of if statement. You can check this by adding
std::cout << a << std::endl;
in your if statement. The system just prints the value of -1*a i.e. (-a)

Resources