"expected expression" error when initializing an empty array [duplicate] - c++

This question already has answers here:
A method to assign the same value to all elements in an array
(4 answers)
Closed 1 year ago.
I am trying to initialize an empty array that I initialized earlier in the program. However, whenever I compile my program I am given the error
expected an expression (C/C++(29))
Here is what my code looks like:
#include <iostream>
using namespace std;
int main(){
const int MAX_SIZE = 6;
int array[MAX_SIZE] = {12,-3,24,65,92,11};
for(int i=0;i<MAX_SIZE;i++){
cout << array[i] << " ";
}
array[MAX_SIZE] = {};
return 0;
}
The error is indicated right on the first curly brace of the empty array initialization. Also I am using Visual Studio Code on a Mac OS Big Sur.

This expression:
array[MAX_SIZE] = {};
Attempts to assign a value at index 6 to something that isn't an array. That's why it generates a compiler error. (And if it didn't, it would be assigning something to an invalid index in an array!)
You might be temped to think this...
array = {};
...would work, since it's similar for resetting members of objects to a default initialized state. But it doesn't work for arrays.
But this works:
std::fill(a, a+MAX_SIZE, 0); // #include <algorithm> if needed
And will assign every element in a to 0
Old school, "C" way for doing the same thing:
memset(a, '\0', MAX_SIZE*sizeof(int)); // #include <string.h> if needed
Or just manually
for (int i = 0; i < MAX_SIZE; i++) {
a[i] = 0;
}

Your trouble lies here: array[MAX_SIZE] = {};
The initialization syntax only work when you are initializing an array.
Though it does actually compile for me with GCC, the resulting program then crashes.
If you want to fill the array with a value. Either zero or something else, you may want to use std::fill.

Plain C-style arrays are not assignable, the type array[size] = {...}; syntax is only for declaration and initialisation.
You can use std::array<T,N> instead, like this:
#include <array>
#include <iostream>
using namespace std;
int main(){
const int MAX_SIZE = 6;
std::array<int, MAX_SIZE> arr = {12,-3,24,65,92,11};
for(int i=0;i<MAX_SIZE;i++){
cout << arr[i] << " ";
}
// reset all elements back to 0
arr.fill(0);
return 0;
}

Related

c++ initial value of global array declarer vs initial value of local function array declarer [duplicate]

This question already has answers here:
Why are global and static variables initialized to their default values?
(5 answers)
Closed 4 days ago.
#include <bits/stdc++.h>
using namespace std;
int a[100]; // <--
int main() {
for (int i = 0; i < 100; i++) {
cout << a[i] << " ";
}
return 0;
}
After declaring the array globally in the above code, all the indices get the value 0.
What is the reason for this?
#include <bits/stdc++.h>
using namespace std;
int main() {
int a[100]; // <--
for (int i = 0; i < 100; i++) {
cout << a[i] << " ";
}
return 0;
}
After declaring the array inside the main function in the above code and printing the values of all the indices of the array, the garbage values at all the indices are found.
In competitive programming I have seen many declare arrays globally in their code. But I don't understand the exact reason
If a variable declaration does not have an explicit initializer specified, and is not (part of) a class/struct type whose constructor initializes its data, then the variable gets default-initialized to zeros at compile-time only when it is declared in global or static scope, whereas it is not default-initialized to anything at all when declared in local scope.

What changed the value in int a? A simple C++ problem confused me

I solved this introduction problem on hackerrank.
Here is something strange when I try to solve this problem.
the input is
4
1 4 3 2
I want to read the numbers into an array.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int a;
int arr[a];
scanf("%d",&a);
for(int i=0; i<=a-1; i++){
scanf("%d",&arr[i]);
printf("i = %d, a = %d\n", i, a);
}
return 0;
}
I got the output:
i = 0, a = 4
i = 1, a = 4
i = 2, a = 4
i = 3, a = 2
The array is correct.
My question is why the value in int a is changed? Why it is changed to 2 instead of 3?
if I rearrange following lines:
int a;
scanf("%d",&a);
int arr[a];
the value in int a is not changed,
i = 0, a = 4
i = 1, a = 4
i = 2, a = 4
i = 3, a = 4
This is wrong:
int a;
int arr[a];
scanf("%d",&a);
Two problems: You are using a before you read the value from the user. Using a unitinitalized is undefined behavior. The output of your code could be anything or nothing.
Then you cannot have a static array with a run-time size. Some compilers support variable length arrays as an extension, but they are not standard c++ (see here).
If you want to write C++, then you should actually use C++. Dynamically sized arrays are std::vector. Your code could look like this:
#include <vector>
#include <iostream>
int main() {
int a;
std::cin >> a; // read user input before you use the value
std::vector<int> x(a); // create vector with a elements
for (size_t i=0; i < x.size(); ++i) {
std::cin >> x[i];
std::cout << "i = " << i << " a = " << a << "\n";
}
}
My question is why the value in int a is changed? Why it is changed to 2 instead of 3?
Undefined behavior means just that, the behavior of your program is undefined. Compilers are not made to compile invalid code. If you do compile invalid code then strange things can happen. Accessing arr[i] is accessing some completely bogus memory address and it can happen that writing to that overwrites the value of a. However, it is important to note that what happens here has little to do with C++, but rather your compiler and the output of the compiler. If you really want to understand the details you need to look at the assembly, but that wont tell you anything about how C++ "works". You can do that with https://godbolt.org/, but maybe the better would be to pay attention to your compilers warnings and try to write correct code.
int a;
int arr[a];
scanf("%d",&a);
This means:
Declare an uninitialised a, with some unspecified value that is not permitted to be used
Declare an array with runtime bounds a (which doesn't exist), which is not permitted
Read user input into a.
Even if these steps were performed in the correct order, you cannot have runtime bounds in C++. Some compilers permit it as an extension, though I've found these to work haphazardly, and it's certainly going to result in strange effects when you use an uninitialised value to do it!
In this case, in practice, you probably have all sorts of weirdness going on in your stack, since you're accessing "non-existent" elements of arr, overwriting the variables on the stack that are "below" it, such as a. Though I caution that trying to analyse the results of undefined behaviour is kind of pointlesss, as they can change at any time for various black-boxed reasons.
Make a nice vector instead.

a function which convert integer to an array of digits c++ [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
#include<iostream>
using namespace std;
int *Arr(int y,int size){
int arg[size];
for(int i=size-1;i>=0;i--){
arg[i]=y%10;
y=y/10;
}
return arg;
}
int main(){
int *p=Arr(2587,4);
for(int j=0;j<4;j++){
cout<<p[j]<<" ";
}
return 0;
}
> Blockquote
I dont why this isn't working ...I'm trying to back an array but the problem is in the second digits.Can somebody help ;) thanks
The problem is you are putting your result into a local array that is destroyed when the function ends. You need to dynamicaly allocate the array so that its life-span is not limited to the function it was created in:
#include<iostream>
using namespace std;
int *Arr(int y, int size)
{
// This local array will be destroyed when the function ends
// int arg[size];
// Do this instead: allocate non-local memory
int* arg = new int[size];
for(int i = size - 1; i >= 0; i--)
{
arg[i] = y % 10;
y = y / 10;
}
return arg;
}
int main()
{
int *p = Arr(2587, 4);
for(int j = 0; j < 4; j++)
{
cout << p[j] << " ";
}
// You need to manually free the non-local memory
delete[] p; // free memory
return 0;
}
NOTE:
Allocating dynamic memory using new is to be avoided if possible. You may want to study up on smart pointers for managing it.
Also, in real C++ code, you would use a container like std::vector<int> rather than a builtin array
Of course it is not working.
At best, the behaviour is undefined, since Arg() is returning the address of a local variable (arg) that no longer exists for main(). main() uses that returned address when it is not the address of anything that exists as far as your program is concerned.
There is also the incidental problem that int arg[size], where size is not fixed at compile time, is not valid C++. Depending on how exacting your compiler is (some C++ compilers reject constructs that are not valid C++, but others accept extensions like this) your code will not even compile successfully.
To fix the problem, have your function return a std::vector<int> (vector is templated container defined in the standard header <vector>). Then all your function needs to do is add the values to a local vector, which CAN be returned safely by value to the caller.
If you do it right, you won't even need to use a pointer anywhere in your code.

Cannot convert Brace-enclosed initializer list

I declare a table of booleans and initialize it in main()
const int dim = 2;
bool Table[dim][dim];
int main(){
Table[dim][dim] = {{false,false},{true,false}};
// code
return 0;
}
I use mingw compiler and the builder options are g++ -std=c++11.
The error is
cannot convert brace-enclosed initializer list to 'bool' in assignment`
Arrays can only be initialized like that on definition, you can't do it afterwards.
Either move the initialization to the definition, or initialize each entry manually.
First, you are trying to assign a concrete element of array instead assigning the full array.
Second, you can use initializer list only for initialization, and not for assignment.
Here is correct code:
bool Table = {{false,false},{true,false}};
You can use memset(Table,false,sizeof(Table)) for this.it will work fine.
Here is your complete code
#include <iostream>
#include <cstring>
using namespace std;
const int dim = 2;
bool Table[dim][dim];
int main(){
memset(Table,true,sizeof(Table));
cout << Table[1][0] << "\n";
// code
return 0;
}

C++ assignment error [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I am new to C++ and I have the code below. I am trying to assign int board[] = create_board();, like I would in java, but it gives me the error
Initializer failed to determine size of board.
Also when I remove that line of code, my print statement is not shown in the command prompt regardless.
Is there something that I am doing wrong in printing the array as well?
Code:
#include <iostream>
using namespace std;
int* create_board() {
int* pointer;
int board[15];
pointer=board;
for(int i=0; i<16; i++)
board[i] = 1;
return pointer;
}
int main () {
int board[] = create_board();
for (int i; i<16; i++)
std::cout << board[i];
return 0;
}
As a beginner, I think you should actually be using std::vector instead of raw pointers. Here is an example of your program that uses it:
#include <iostream>
#include <vector>
std::vector<int> create_board()
{
return std::vector<int>(16, 1); // declare 16 integers whose value is 1
}
int main()
{
std::vector<int> board = create_board();
for (int i = 0; i < 16; ++i)
std::cout << board[i];
}
In C++11, this might look like the following:
#include <iostream>
#include <array>
int main()
{
std::array<int, 16> array{};
array.fill(1);
for (auto var : array) std::cout << var << '\n';
}
Two things wrong really:
You can't use an array as an lvalue, instead you need to use a pointer. E.g.
int* board = create_board();
The bigger issue, however, is that in your create_board() function you are returning a pointer to a stack-based array that will be destroyed as soon as your function returns. You need to either allocate this using malloc or new, or make it static in order to return a pointer to it that can be used outside the function.
Memory management is very tricky. You should read more about it before trying to mess with manual memory. I'd recommend sticking with stl collections and the like for now.
As for the actual question, the array you declared lives on the stack, meaning that it disappears as soon as the function returns. This means that the pointer you returned is now a dangling pointer, meaning that accessing it gives undefined behavior.
You've also got an off by one error. You made an array of size 15, but you're accessing 16 elements of it.
Here's how things might look if you were using a std::array (essentially a type safe, collection like wrapper over raw arrays) and returned by value instead of pointer (keep things simple for now).
For normal arraylike collections, you'd use a std::vector, but for a small fixed size array like this, you might as well just use std::array. Vectors are the C++ equivalent of Java's ArrayList, so they can change size.
#include <iostream>
#include <array>
std::array<int, 16> create_board()
{
std::array<int, 16> board;
for(int i=0; i<16; i++)
board[i] = 1;
return board;
}
int
main ()
{
std::array<int, 16> board = create_board();
for (int i; i<16; i++)
std::cout << board[i];
return 0;
}