C++ "dynamic" arrays - c++

I've got some problems/misunderstandings with arrays in C++.
int myArray[30];
myArray[1]=2;
myArray[2]=4;
This is spitting out a lot of compiler errors. I don't think it is necessary to include them here as this is an easy question for everybody with experience in C(++) I guess
Why doesn't this work?
Is there a way to create a "dynamic" array that has a fixed ammount of values (so no malloc needed) but where I can change the values during runtime?

I'm guessing you have that outside of a function.
You are allowed to define variables outside of a function. You can even call arbitrary code outside of a function provided it is part of a variable definition.
// legal outside of a function
int myArray[30];
int x = arbitrary_code();
void foo()
{
}
But you cannot have arbitrary statements or expressions outside of a function.
// ILLEGAL outside a function
myArray[1] = 5;
void foo()
{
// But legal inside a function
myArray[2] = 10;
}

Are you saying that this doesn't compile:
int main() {
int myArray[30];
myArray[1]=2;
myArray[2]=4;
}
If it doesn't, you have something wrong with your compiler setup. As I said in my comment, we need to see the error messages.

Related

Why should global array size be an integer constant?

In C++ I tried declaring a global array of some size. I got the error:
array bound is not an integer constant before ‘]’ token
But when I declared an array of the same type in the main() function it is working fine.
Why is there different behaviour here?
int y=5;
int arr[y]; //When I comment this line it works fine
int main()
{
int x=5;
int arr2[x]; // This line doesn't show any error.
}
Edit: Many are suggesting this question is a duplicate of Getting error "array bound is not an integer constant before ']' token". But that question doesn't answer why there is different behaviour.
Both examples are ill-formed in C++. If a compiler does not diagnose the latter, then it does not conform to the standard.
Why there is a different behaviour here?
You use a language extension that allows runtime length automatic arrays. But does not allow runtime length static arrays. Global arrays have static storage.
In case you are using GCC, you can ask it to conform to the standard by using the -pedantic command line option. It is a good idea to do so in order to be informed about portability problems.
The size of an array must be a constant. You can fix this by declaring y as const.
const int y=5;
int arr[y];
As for why this worked in main, g++ does allow a variable length array in block scope as an extension. It is not standard C++ however.
Both shouldn't be used, one works because (as #eerorika said) automatic length arrays are allowed on runtime, but global arrays need to have static storage.
If you want to declare an array with a variable size (e.g. given by std::cin) you would do something along the lines of:
int x;
std::cin >> x;
const int n = x;
float arr[n];
But you wouldn't be able to set it to contain just zeros with float arr[n] = {0} (if you need to add to a value in the array, not being sure you set it), you would need to use a loop like that
for(int i = 0; i < n; i++)
{
arr[i] = 0;
}
The type-system of C++ handles these C-like arrays in a way that it defines arr2 from your example of type int[5]. So, yes the number of elements of the array is part of the type!
This puts some constraints on what you are allowed to use in the definition of C-like arrays. I.e. this number needs to have static storage, needs to be immutable and needs to be available at compile time.
So, you might want to change your code to something like the following, which will have another goodie. It initializes the array in a proper way:
int arr2[] = {0, 0, 0, 0, 0};

What is the difference between constant declaring Global or declaring inside a function where it is used [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
i am declaring a constant (a large structure constant containing string) inside a function and it is used only inside this function.
will it have any execution time impact on my program? '
They will be created every time the function is called (take more time) or only once and the reference will be used through out its life.
If i declare the constant outside the function (global) will it be faster in execution ?
Actually, declaring variables inside of a function is a great practice. If that variable is only to be used inside of that function of course. There won't be any performance differences between the two methods, but making the constant global may require a more creative naming scheme while the one inside the function can be generic. It is only being used inside of that function, after all.
static struct can help you setting it up once and be done with it. This will be coming from data segment and initialise during at the startup. A raw and dirty code below, but will give you some intuition.
#include <stdio.h>
struct A {
int a;
int b;
};
void func(void)
{
static struct A a = {5,3};
printf("FUNC: A.a: %d\n", a.a);
}
int main(int argc, char **argv)
{
static struct A a = {6,4};
printf("MAIN: A.a: %d\n", a.a);
func();
return 0;
}
I would personally move it out of the function body if any other related functions use the variable, as long as you're using namespaces.
Also if its a true constant, I believe you can declare a struct static constexpr, which means that it won't be allocated on the stack every time the function is called (static), even if you declare it inside the function body. It also means that where it can be used at compile time, it will be (constexpr).
#include <iostream>
namespace Test{
struct Test {
char name[11];
int a;
int b;
};
static constexpr Test TEST_CONSTEXPR = {
"test value",
5,
6
};
}
int main()
{
std::cout << Test::TEST_CONSTEXPR.name << std::endl;
std::cin.get();
return 0;
}
In Ada this is compiler dependent. (As performance usually is.)
As "constants" are not compile-time static, a compiler may do the safe thing and evaluate the initialising expression every time the constant is declared.
If it really matters, measure what your compiler does.

Declaring variables in C/C++

Someone told me: "declaring variables close to their use have value". He corrected me:
void student_score(size_t student_list_size) {
// int exam;
// int average;
// int digit;
// int counter_digits;
for (size_t i = 0; i < student_list_size; i++) {
int exam;
int average;
int digit;
int counter_digits;
I think it's bad, because here variables initialized every loop. What's true?
I encourage to declare them in as local a scope as possible, and as close to the first use as possible. This makes it easier for the reader to find the declaration and see what type the variable is and what it was initialized to. And of course, compiler will optimize it.
Both methods would be optimised to the same thing by the compiler. But for readability and ease of future maintenance, declaring the variables within the loop might be preferred by some.
I think it's bad, because here variables initialized every loop. What's true?
The code given the variables are not initialised at all.
So it is just a matter of personal taste.
It depends. C and C++ work differently in that regard. In C, variables MUST be declared at the start of its scope (forget that, it depends on your compiler although it holds true in pre-C99 compilers, as pointed out in the comments - thanks guys!), while in C++ you can declare them anywhere.
Now, it depends. Let's suppose the following two pieces of code:
int i = 0;
while (i < 5) {
i++;
}
while (i < 5) {
int i = 0;
i++;
}
In this case, the first piece of code is what's gonna work, because in the second case you declare the variable at each loop. But, let's suppose the following...
int i = 0;
while (i < 5) {
std::String str = "The number is now " + std::to_string(i);
cout << str << endl;
i++;
}
In short, declare the variables where it makes most sense to you and your code. Unless you're microoptimizing, like most things, it all depends on context.
This seems like a discussion with many personal opinions, so I'll add mine: I am a C programmer and like the C rules of having to declare your variables at the begining of a function (or block). For one thing, it tells me the stack lay-out so if I create another bug (I do "occassionaly") and overwrite something, I can determine the cause from just the stack lay-out. Then, when having to go through C++ code, I always have to search where the variable is declared. I rather look at the function beginning and see them all neatly declared.
I do ocassionally want to write for (int i=0;... and know the variable goes out of scope following the for loop (I hope it goes out of scope, as it is declared before the block begins).
Then there is an example in another answer:
while (i < 5) {
int i = 0;
i++;
}
and I hope it doesn't work because if it works it means there must be a variable i declared before this loop and so you have a clash of variables and scopes which can be horrible to debug (the loop will never terminate because the wrong i is incremented). I mean, I hope all variables must have been declared before their use.
I believe you must have a discipline in declaring your variables. The discipline can vary per person, just as long as it is easy to find where a variable is declared and what its scope is.
First of all that is not valid C code unless you are using -std=c99.
Furthermore, as long as you aren't creating dangling pointers in the loop, there is no problem with it.
The advantage you gain from doing it this way is that these variables are in a tight knit scope.
You need to know some knowledge of what local variable is ?
A variable declared inside a function is known as local variable. Local variables are also called automatic variables.
Scope: The area where a variable can be accessed is known as scope of variable.
Scope of local variable:
Local variable can be used only in the function in which it is declared.
Lifetime:
The time period for which a variable exists in the memory is known as lifetime of variable.
Lifetime of local variable:
Lifetime of local variables starts when control enters the function in which it is declared and it is destroyed when control exists from the function or block.
void student_score(size_t student_list_size) {
// int exam;
// int average;
// int digit;
// int counter_digits;
/* The above variable declared are local to the function student_score and can't be used
in other blocks. In your case its the for loop. */
for (size_t i = 0; i < student_list_size; i++) {
int exam;
int average;
int digit;
int counter_digits;
...
/* The above declared variable are local to the for loop and not to the function.*/
Consider this example:
#include<stdio.h>
void fun();
int main()
{
fun();
return 0;
}
void fun()
{
int i,temp=100,avg=200;
for (i=0;i<2;i++)
{
int temp,avg;
temp = 10 + 20;
avg = temp / 2;
printf("inside for loop: %d %d",temp,avg);
printf("\n");
}
printf("outside for loop: %d %d\n",temp,avg);
}
Output:
inside for loop: 30 15
inside for loop: 30 15
outside for loop: 100 200
If you are declaring the variable in loops the then declare the variable as static (In case if the value of the variable to be saved/used for further iteration).
Even compiler spend lot of time to initialize the variable in loops.
My suggestion is to declare at the beginning of the function. its a good programming practice.
I think, i made my point.

Programming with global variables giving wrong results

I've been coding for a while in other languages and am pretty proficient, but now I am diving more deeply into C++ and have come across some weird problems that I never had in other languages. The most frustrating one, which a google search hasn't been able to answer, is with two different code orders.
The background is that I have an array of integers, and a pointer an element in the array. When I go to print the pointer one method prints correctly, and the other prints nonsense.
An example of the first code order is:
#include <iostream>
using namespace std;
void main(){
int *pAry;
int Ary[5]={2,5,2,6,8};
pAry=&Ary[3];
cout<<*pAry<<endl;
system("pause");
}
and it works as expected. However this simple order wont work for the full project as I want other modules to access pAry, so I thought a global define should work, since it works in other languages. Here is the example:
#include <iostream>
using namespace std;
int *pAry;
void evaluate();
void main(){
evaluate();
cout<<*pAry<<endl;
system("pause");
}
void evaluate(){
int Ary[5]={2,5,2,6,8};
pAry=&Ary[3];
}
When I use this second method the output is nonsense. Specifically 1241908....when the answer should be 6.
First I would like to know why my global method isn't working, and secondly I would like to know how to make it work. Thanks
In the second example, Ary is local to the function evaluate. When evaluate returns, Ary goes out of scope, and accessing it's memory region results in undefined behaviour.
To avoid this, declare Ary in a scope where it will still be valid at the time you try to access it.
It's not working because your pAry is pointing into a local array, which is destroyed when you return from evaluate(). That's undefined behavior.
One possible fix is to make your local array static:
static int Ary[5]={2,5,2,6,8};
In the evaluate() function, you're aiming pAry at a variable (actually array element) local to that function. A pointer can only be dereferenced as long as the object to which it points still exists. Local objects cease to exist when they go out of scope; in this case, this means all elements of Ary cease to exist when evalute() ends, and thus pAry becomes a dangling pointer (it doesn't point anywhere valid).
Dereferncing a dangling pointer gives undefined behaviour; in your particular case, it outputs a garbage value, but it might just as well crash or (worst of all) appear to work fine until the program changes later.
To solve this issue, you can either make Ary global as well, or make it static:
void evaluate(){
static int Ary[5]={2,5,2,6,8};
pAry=&Ary[3];
}
A static local variable persists across function calls (it exists from first initialisation until program termination), so the pointer will remaing valid.
The problem is that you need to declare Ary with file scope.
int Ary[] = {1,2,3,4,5};
void print_ary(void); // The void parameter is a style thingy. :-)
int main(void)
{
print_ary();
return EXIT_SUCCESS;
}
void print_ary(void)
{
for (unsigned int i = 0; i < (sizeof(Ary) / sizeof(Ary[0]); ++i)
{
std::cout << Ary[i] << std::endl;
}
}
A better solution would be to pass a std::vector around to your functions rather than using a global variable.

c++ class function aliases

I was wondering if there was a simple way to write an alias of a c++ class function. For instance, if I have some list container object, a logical function would be
int list::length() { return len; }
But another logical alias that programmers might use could be
int list::size() { return len; }
So, instead of writing both functions with their full body, is there any way to make list::size() an alias of list::length() such that it isn't a duplicate when compiled, but rather references the same function?
I've read that you can do this with #define, but I don't want to cause any confusion with other code-names somewhere totally out of scope (i.e. a 'size' variable).
I've also read that function pointers can fix it, but that isn't exactly an alias (since it has to apply de-referencing), nor can function pointers be given a declaration, giving it a confusing help-line to users (I would think), plus the confusion if ever I need to nest my code inside another object (I have to adjust the scope).
One of my guesses is, will the following be taken as a direct function alias by most optimizing compilers:
inline int list::length() { return len; }
inline int list::size() { return length(); }
Or, is there any strict 'alias' syntax for c++? (I couldn't find any - wasn't sure)
So then, what would be the most efficient way of doing this?
EDIT: I've accepted the answer simply to wrap up the question, since it's only a curiosity of mine. Anyone with good information, please add comments or answer, and I may even change my answer.
I would not use the preprocessor and #define to do this. In general preprocessor should be a last resort in C++. See this C++ FAQ on inline functions which also contains a section on the various evils of using macros of the preprocessor.
The approach I would use would be to have a function that will have several different aliases with a more complicated function and interface you would do something like the following:
int list::length(string xString, int iValue) {
int iReturnValue = 0; // init the return value
// do stuff with xString and iValue and other things
return iReturnValue;
}
Then do something like the following for an alias.
inline int list::size(string xString, int iValue) {return length(xString, iValue);}
The inline should basically just replace the alias with the actual function call.
See also this stack overflow posting Giving a function implementation more than one name. It provides some reasons why you might not want to do this.