Nested for loop only runs inner loop (c++) - c++

I am quite new to c++, and I believe the answer to my problem is very, very simple.
I've been using the Eclipse IDE, but have recently changed to a simple text editor and using the command line for compiling. (As i currently don't have my own computer, and I am not allowed to install anything on the one I am using).
However, while writing a program, I noticed that whenever I had nested loops, it would only run the inner loop.
I've tried compiling my code using different online compilers, which results in the same problem.
Because of this, I believe that the problem is related to something simple, that Eclipse was taking care of automatically.
#include <iostream>
int main() {
for (int i; i<3; i++) {
for (int j; j<3; j++) {
std::cout << j << std::endl;
}
}
return 0;
}
Above is the simplest example, I could think of, that produces the problem.
The expected output is 0, 1, 2, 0, 1, 2, 0, 1, 2, however it only outputs 0, 1, 2 when I compile and run it.

You're not initializing the i and j variables to 0, so the variables start off by having undefined values. Fix to:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
std::cout << j << std::endl;
}
}

The problem is that you are using uninitialized variables, which leave them with undefined values
for (int i; i < 3; i++) {
^
Try with
for (int i = 0; i < 3; i++) {

Related

C++ Convert one exact string element into an int

I want to create a string array and then after writing lines into it I want to change one exact character into int. I already know that all the characters are going to be numbers. As my goal is to change the one character at a time, options like atoi, stoi etc. are perhaps off? The closest I got is that:
#include <iostream>
int main()
{
int n=0,suma=0,i=0;
int multiplier[11]={1,3,7,9,1,3,7,9,1,3,1};
std::cin>>n;
std::string str[n];
for (int i = 0; i < n; ++i)
{
std::cin>>str[i];
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < 11; ++j)
{
i = str[i][j] - '0';
std::cout << i;
}
}
}
Although this is the output I get
"1-48"
I know that the string is going to be 11 characters long. Any ideas?
EDIT: It was a single typo that caused my confuse :p Yet still I'm looking forward to read and learn from your suggestions such as using different way to read n (from user input) strings. :)
In your loop:
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < 11; ++j)
{
i = str[i][j] - '0';
std::cout << i;
}
}
you are modifying outer loop variable i (looks like for the purpose of printing a value).
Given an unfortunate input, you would go out-of-bounds fast.

segmentation fault knapsackproblem

I wrote this knapsack problem solution in c++ however when I run it, it gives me segmentation fault
I have tried everything and my compiler will always give me the segmentation fault error.
#include<iostream>
#include<algorithm>
int knapsack(int v[],int w[],int n,int W)
{
int V[n][W];
for(int i = 0; i<=W;i++)
{
V[0][i] = 0;
}
for(int i = 0; i <= n; i++){
for(int j = 1; j<=W; j++)
{
if(w[i]<=W)
{
V[i][j] = std::max(V[i-1][j], v[i]+V[i-1][j-w[i]]);
}
else
{
V[i][j] = V[i-1][j];
}
}
}
return V[n][W];
}
int main()
{
int v[4] = {10,40,30,50};
int w[4] = {5,4,6,3};
int n = 3;
int W = 10;
std::cout<<"item value:"<<knapsack(v,w,n,W);
}
Don't use VLAs. The size of an array must be known at compile time, else it's not standard C++. Those are compiler extensions that are not portable and introduce some hidden costs.
Array indices go from 0 to length-1. in you loop
for(int i = 0; i<=W;i++)
i can reach W, then V[0][W] is out of bounds which causes the seg fault. You have to use < instead of <=:
for(int i = 0; i < W; i++)
n should probably be 4, if it's meant to represent the size of the array, a std::vector would make your life easier here, because a vector knows it's size
In general don't use C-style arrays or raw pointers at all in this day and age, use std::vector instead.
int V[n][W];
for(int i = 0; i<=W;i++)
{
V[0][i] = 0;
}
Note that V's indexes go from V[0][0] to V[0][W-1]. Your for loop will try to read V[0][W].
The same error is repeated in other places. Your end condition in your for loops should be < (strictly less) instead of <= (less or equal than).

What does third 'for' mean in #define for for(int z=0;z<2;++z)for

I have found a piece of code in a C++ program, it seems that it loops two times every for() loop in this program, but why does it need this third for in such preprocessor definition?
#define for for(int z=0;z<2;++z)for
It replaces for with for(int z=0;z<2;++z)for. Obviously, that would turn
for (int i = 0; i < N; ++i) {
// ...
}
into
for (int z=0;z<2;++z) for (int i = 0; i < N; ++i) {
// ...
}
Thus creating two nested loops. Without that extra for it would be
for (int z=0;z<2;++z) (int i = 0; i < N; ++i) {
// ...
}
Which is obviously incorrect.
Note that even though it's “correct” in the form you gave in your question, it doesn't mean it's a “good practice”. This is an example of excessive macro abuse and must be avoided. Here is one of the numerous examples how it could go wrong:
for (int z = 0; z < 5; ++z) {
for (int i = 0; i < 3; ++i) {
std::cout << z << std::endl; // this will never print 2, 3, 4
}
}
This will expand into
for (int z=0;z<2;++z) for (int z = 0; z < 5; ++z) {
for (int z=0;z<2;++z) for (int i = 0; i < 3; ++i) {
std::cout << z << std::endl; // this will never print 2, 3, 4
}
}
Meaning that you now have four nested loops, and that the inner loop will print the “invisible” z instead of the z you have declared in the outer loop (which becomes the second-level loop in the expanded code).
Another reason: as pointed by #stefan, it's a very bad idea to use keywords or other well-known identifiers as macro names. Makes one think of the infamous #define true false. And, as #HolyBlackCat mentions, it's also undefined behavior, meaning that as far as the standard is concerned, anything could happen. Ranging from the code “seemingly working” to a full-blown World War III with Martians (who invaded Earth to cleanse it from ugly code).
Firstly, that macro is the ugliest thing I've ever seen. I don't recommend ever doing something like this.
The top answer from Sergey Tachenov is really great, but it should also be mentioned that this macro really makes every for loop run twice. This means the doubly nested loops shown below will execute 400 times (not 200 times)! This might be unexpected.
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
// I'll be executed 100 times without the macro
}
}
becomes
for (int z=0;z<2;++z) for (int i = 0; i < 10; i++) {
for (int z=0;z<2;++z) for (int j = 0; j < 10; j++) {
// I'll be executed 400 times with the macro
}
}
It only gets worse from here. Consider an infinte loop like
int some_condition = 0;
for(;;) {
// insert logic here for calculating whether to break out
if (some_condition) {
some_condition = 0; // set back to false for use down the line
break;
}
}
turns into
int some_condition = 0;
for (int z=0;z<2;++z) for (;;) {
// insert logic here for calculating whether to break out
if (some_condition) {
some_condition = 0; // set back to false for use down the line
break; // gets me out of for(;;)...but the outer loop repeats
}
}
which bumps you out of the inner infinite loop if the condition is met....only to go right back in it. Now you might be stuck in an infinite loop.
Unexpected behavior is a good reason to avoid something, and macro shenanigans like this is very dangerous, and could be a real b**ch to debug. Imagine if some include directive had this ported in several header files deep...
Preprocessor substitution occurs in a single pass and does not support recursion. So the second "for" is probably for some zany idea of chaining existing "for" loops, prepending them with the macro "for" loop portion.
#define for for(int z=0;z<2;++z)for
Thus it replaces
for (int i = 0; i < N; ++i)
{
// ...
}
with
for(int z=0;z<2;++z)
for (int i = 0; i < N; ++i)
{
// ...
}
Which is a pretty crazy use of the preprocessor.

Confused about 2D arrays in C++

I'm having problems with creating a 2D boolean array in C++. I wrote a quick program for create and print all the bool array.
#include <iostream>
using namespace std;
int main() {
const int WIDTH = 20;
const int HEIGHT = 20;
bool world [HEIGHT][WIDTH];
for(int i = 0; i < HEIGHT; i++){
for(int j = 0; j < WIDTH; j++){
world[i][j] = true;
}
}
for(int i = 0; i < HEIGHT; i++){
for(int j = 0; j < WIDTH; j++){
if(world[i][j]){
cout << j;
}else{
cout << ' ';
};
}
cout << "-" << i << endl;
}
return 0;
}
And this is his output.
012345678910111213141516171819-0
012345678910111213141516171819-1
012345678910111213141516171819-2
012345678910111213141516171819-3
012345678910111213141516171819-4
012345678910111213141516171819-5
012345678910111213141516171819-6
012345678910111213141516171819-7
012345678910111213141516171819-8
012345678910111213141516171819-9
012345678910111213141516171819-10
012345678910111213141516171819-11
012345678910111213141516171819-12
012345678910111213141516171819-13
012345678910111213141516171819-14
012345678910111213141516171819-15
012345678910111213141516171819-16
012345678910111213141516171819-17
012345678910111213141516171819-18
012345678910111213141516171819-19
It creates a 2D array, set all his values to true, and print the array. This is fine, the problem is when the 2d array get bigger. For example if I change the size of WIDTH and HEIGHT to 30, when i print the array I have the following ouput:
01234567891011121314151617181920212223242526272829-0
01234567891011121314151617181920212223242526272829-1
01234567891011121314151617181920212223242526272829-2
01234567891011121314151617181920212223242526272829-3
01234567891011121314151617181920212223242526272829-4
01234567891011121314151617181920212223242526272829-5
01234567891011121314151617181920212223242526272829-6
01234567891011121314151617181920212223242526272829-7
01234567891011121314151617181920212223242526272829-8
01234567891011121314151617181920212223242526272829-9
01234567891011121314151617181920212223242526272829-10
01234567891011121314151617181920212201234567891011121314151617181920212223242526272829-11
01234567891011121314151617181920212223242526272829-12
01234567891011121314151617181920212223242526272829-13
01234567891011121314151617181920212223242526272829-14
01234567891011121314151617181920212223242526272829-15
01234567891011121314151617181920212223242526272829-16
01234567891011121314151617181920212223242526272829-17
01234567891011121314151617181920212223242526272829-18
01234567891011121314151617181920212223242526272829-19
01234567891011121314151617181920212223242526272829-20
01234567891011121314151617181920212223242526272829-21
01234567891011121314151617181920212223242526272829-22
01234567891011121314151617181920212223242526272829-23
01234567891011121314151617181920212223242526272829-24
01234567891011121314151617181920212223242526272829-25
01234567891011121314151617181920212223242526272829-26
01234567891011121314151617181920212223242526272829-27
01234567891011121314151617181920212223242526272829-28
01234567891011121314151617181920212223242526272829-29
As you can see on the line 11 it counts until 22 and restart the for loop for j. I don't know what is wrong, I need an 2D array of bools of size [50][50] but I don't what is wrong there.
EDIT: The problem is the compiler. I tried the same code on GCC compiler on a Linux machine and works perfectly. This code works fine, the problem is the compiler or the compiler with the CLion IDE. It compiles but I have problems with the running or the output produced. The code works fine with GCC compiler or on an Unix machine
Okay this is logically absolutely correct and i have tested your code on online compiler using 20 as well as 30. restart your compiler or try another compiler a reliable one... Here is the screenshot of your result when i executed your code online.
The line
bool world [WIDTH][HEIGHT];
Should be
bool world [HEIGHT][WIDTH];
As the i in your loop ranges from 0 to HEIGHT-1. j ranges from 0 to WIDTH-1

Noobish Array problems: Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted

I'll be pretty honest/upfront here- I'm both a noob to C++, to computer programming in general, and additionally, to this site as well. I'll just preface my question by saying that I did in fact look at other questions possibly related to my own, but it just felt like they were outside of my scope. With that said, here's my problem:
I get this error message:
"Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted."
Here's my code. It's just a basic little thing for some array practice. The function multiTable outputs a multiplication table:
#include <iostream>
#include <iomanip>
using namespace std;
void multiTable();
int main()
{
multiTable();
return 0;
}
//Prints a 9 by 9 multiplication table;
void multiTable()
{
const int row = 9, col = 9;
int arr[row][col];
for(int i = 1; i <= row; i++)
{
for(int j = 1; j <= col; j++)
{
arr[i][j] = j * i;
cout << setw(3);
cout << arr[i][j];
}
cout << endl;
}
}
I also want to mention that instead of the function call, had I just included all of the code contained within the function body in main, I don't get the run-time error. Why is it that when it's contained within a function, I get the runtime error, but when it's just in main, I don't get the error? And of course, what would I have to change in order for the function call to not produce the error?
Those are your problems: for(int i = 1; i <= row; i++) and for(int j = 1; j <= col; j++) array counting starts from 0. So your for loops should be like this (starting from 0 and omitting the = part from <=):
for(int i = 0; i < row; i++) and for(int j = 0; j < col; j++)