Why is my empty array not empty? - c++

I write the following code and set a breakpoint in xcode:
#include <iostream>
using namespace std;
int main(int argc, const char * argv[])
{
int array[12];
return 0; //Set breakpoint here
}
The debugger panel shows the first 6 elements contain non zero ints. Why is this?

int array[12];
This declares an array with 12 elements, not an empty array.
Furthermore it declares them without an initializer, which (in function scope) means that they will be default initialized. For int that means no initialization is performed and the resulting ints will have indeterminate values. This behavior is defined in the specification for C++.
If you want to zero initialize the array then you need to give it an initializer:
int array[12] = {};
The reason that this is not forced behavior is that there is a performance cost to initialization and some programs are written to work correctly without needing to suffer that penalty.

Because you only declared the array, not initialized it.
When you declare the only thing that happens is that you reserve a certain area of memory. What is already stored on that area can be anything left over from other operations/programs.

Only global and static variables (incl. arrays) are assured to have zero initial values. For local arrays (as in your code) you can initialize to zeroes using:
int array[12] = {0};
Check this link for more details:
How to initialize array to 0 in C?

The C++ compiler does not initialize variables unless you tell it to.

Because your array is not initialized. Debugger panel is showing you the previous value stored at that locations.

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};

Assigning value to struct's field, change also other variable

Simple code
#include <iostream>
using namespace std;
struct foo {
int bar;
};
struct foo tab[2];
int sum = 0;
int main()
{
tab[2].bar = 3; //this change 'sum' value!
cout << sum << endl;
return 0;
}
result in 3 instead of 0. It is unbelievable, so problably I am missing something. What I have done wrong?
Arrays start at 0, so tab[2] would be the third element, but you only allocated 2 of them.
In this case, sum is in the memory directly after tab, so when you go to where the third tab would be, you're actually in the memory for sum.
Notice that you access tab[2] which is an overflow (its size is 2 so valid indices are 0 and 1).
So tab[2] accesses the memory address of sum.
When you declare your variable
struct foo tab[2];
tab[2] does not exist.
You can only do
tab[0].bar = 3
tab[1].bar = 3
because arrays index starts from 0 and ends at arraySize-1.
If you look closely tab has a length of 2. By accessing the index 2, you are accessing memory out of the tab, which means you are accessing sum.
This is the reason why you are changing sum.
First of all, turn on compiler warnings! If you'd allow the compiler to help you, then it would very likely point out the exact error in this line:
tab[2].bar = 3; //this change 'sum' value!
Depending on which compiler you use, the warning may be as follows:
warning: array subscript is above array bounds
struct foo tab[2]; has two elements with indices 0 and 1, you try access a non-existing 3rd element. This results in undefined behaviour of your program. Whatever results you got, it was just random. Your program could also randomly crash.
Note that your code is also half C and half C++. That's not good. You don't need to write struct foo when you want to refer to the foo type, it's enough to write foo. Instead of a raw array, std::array<Foo, 2> can be used. And using namespace std; should not be used by default.

Defining Array C/C++

What is the difference between this two array definitions and which one is more correct and why?
#include <stdio.h>
#define SIZE 20
int main() {
// definition method 1:
int a[SIZE];
// end definition method 1.
// defintion method 2:
int n;
scanf("%d", &n);
int b[n];
// end definition method 2.
return 0;
}
I know if we read size, variable n, from stdin, it's more correct to define our (block of memory we'll be using) array as a pointer and use stdlib.h and array = malloc(n * sizeof(int)), rather than decalring it as int array[n], but again why?
It's not "more correct" or "less correct". It either is xor isn't correct. In particular, this works in C, but not in C++.
You are declaring dynamic arrays. Better way to declare Dynamic arrays as
int *arr; // int * type is just for simplicity
arr = malloc(n*sizeof(int*));
this is because variable length arrays are only allowed in C99 and you can't use this in c89/90.
In (pre-C99) C and C++, all types are statically sized. This means that arrays must be declared with a size that is both constant and known to the compiler.
Now, many C++ compilers offer dynamically sized arrays as a nonstandard extension, and C99 explicitly permits them. So int b[n] will most likely work if you try it. But in some cases, it will not, and the compiler is not wrong in those cases.
If you know SIZE at compile-time:
int ar[SIZE];
If you don't:
std::vector<int> ar;
I don't want to see malloc anywhere in your C++ code. However, you are fundamentally correct and for C that's just what you'd do:
int* ptr = malloc(sizeof(int) * SIZE);
/* ... */
free(ptr);
Variable-length arrays are a GCC extension that allow you to do:
int ar[n];
but I've had issues where VLAs were disabled but GCC didn't successfully detect that I was trying to use them. Chaos ensues. Just avoid it.
Q1 : First definition is the static array declaration. Perfectly correct.
It is when you have the size known, so no comparison with VLA or malloc().
Q2 : Which is better when taking size as an input from the user : VLA or malloc .
VLA : They are limited by the environment's bounds on the size of automatic
allocation. And automatic variables are usually allocated on the stack which is relatively
small.The limitation is platform specific.Also, this is in c99 and above only.Some ease of use while declaring multidimensional arrays is obtained by VLA.
Malloc : Allocates from the heap.So, for large size is definitely better.For, multidimensional arrays pointers are involved so a bit complex implementataion.
Check http://bytes.com/topic/c/answers/578354-vla-feature-c99-vs-malloc
I think that metod1 could be little bit faster, but both of them are correct in C.
In C++ first will work, but if you want to use a second you should use:
int size = 5;
int * array = new int[size];
and remember to delete it:
delete [] array;
I think it gives you more option to use while coding.
If you use malloc or other dynamic allocation to get a pointer. You will use like p+n..., but if you use array, you could use array[n]. Also, while define pointer, you need to free it; but array does not need to free.
And in C++, we could define user-defined class to do such things, and in STL, there is std::vector which do the array-things, and much more.
Both are correct. the declaration you use depends on your code.
The first declaration i.e. int a[size]; creates an array with a fixed size of 20 elements.
It is helpful when you know the exact size of the array that will be used in the code. for example, you are generating
table of a number n up till its 20th multiple.
The second declaration allows you to make an array of the size that you desire.
It is helpful when you will need an array of different sizes, each time the code is executed for example, you want to generate the fibonacci series till n. In that case, the size of the array must be n for each value of n. So say you have n = 5, in this case int a [20] will waste memory because only the first five slots will be used for the fibonacci series and the rest will be empty. Similarly if n = 25 then your array int a[20] will become too small.
The difference if you define array using malloc is that, you can pass the size of array dynamically i.e at run time. You input a value your program has during run time.
One more difference is that arrays created using malloc are allocated space on heap. So they are preserved across function calls unlike static arrays.
example-
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n;
int *a;
scanf("%d",&n);
a=(int *)malloc(n*sizeof(int));
return 0;
}

Pointer to int array, passing and using it from another method

I haven't cemented my learning of C++ arrays and have forgotten how to do this properly. I've done it with char array before but its not working as well for int array.
I declare a new blank int array:
int myIntArray[10];
So this should be an array of nulls for the moment correct?
Then I assign a pointer to this array:
int *pMyArray = myIntArray
Hopefully thats correct to there.
Then I pass this to another method elsewhere:
anotherMethod(pMyArray)
where I want to assign this pointer to a local variable (this is where I'm really not sure):
anotherMethod(int *pMyArray){
int myLocalArray[];
myLocalArray[0] = *pMyArray;
}
I'm not getting any compilation errors but I'm not sure this is right on a few fronts. Any and all help and advice appreciated with this.
Edit:
I should have said what I am trying to do.
Very simple really, I'd just like to modify a local array from another method.
So I have:
Method 1 would contain:
int myArray1[10] = {0};
Method 2 would be passed the pointer to myArray:
Then some code to modify the variables in the array myArray.
int myIntArray[10];
This is an uninitialized array. It doesn't necessarily contain 0's.
int *pMyArray = myIntArray
Okay, pMyArray points to the first element in myIntArray.
anotherMethod(int *pMyArray){
int myLocalArray[10];
myLocalArray[0] = *pMyArray;
}
This doesn't assign your pointer to anything, it assigns the first value of the local array to the int pointed to by pMyArray, which, remember, was uninitialized. I added the 10 there because you can't have an array of unknown size in C++.
To modify what pMyArray points to, you need to pass it by reference:
anotherMethod(int *& pMyArray)
Also, if you assign it to some values in automatic storage, it will result in undefined behavior, as that memory is no longer valid when the function exits.
int myIntArray[10];
So this should be an array of nulls for the moment correct?
No, this is an array of 10 integers containing values depending on the storage specification.
If created locally, it has random garbage values.
If created globally it is value initialized which is zero initialized for POD.
Besides that your method just assigns the local array with the first vale of the array you pass.
What are you trying to do exactly? I am not sure.
int myIntArray[10];
So this should be an array of nulls for the moment correct?
Not correct, it is an array of 10 uninitialized ints.
int *pMyArray = myIntArray
Hopefully thats correct to there.
Not quite correct, pMyArray is a pointer to the 1st element, myIntArray[0].
where I want to assign this pointer to a local variable (this is where
I'm really not sure):
If you really need to assign the pointer, you have to use this code
int *p_myLocalArray;
p_myLocalArray = pMyArray;
There are a few mistakes here.
First, array of zeros (not nulls) is achieved by using the initializer syntax:
int myIntArray[10] = {0};
Second, int myLocalArray[]; has a size of 0. And even if it did have a size of, say, 10, writing myLocalArray[0] = *pMyArray; will assign the first int from pMyArray into mLocalArray, which is not what you meant.
If you want to assign a pointer of the array, then simply:
int *myLocalPointer;
myLocalPointer = pMyArray;
If you want a local copy of the array, you will need to copy it locally, and for that you also need the size and dynamic allocation:
void anotherMethod(int *pMyArray, int size){
int *myLocalArray = (int *)malloc(size * sizeof(int));
memcpy(myLocalArray, pMyArray, size * sizeof(int));
...
free(myLocalArray);
}

Can't set variable length with variable

What I'm trying to do right now is to create an array with a length that is defined by a variable. However, when I put the variable in the array length, it gives me a "Variable length array of non-POD element type 'glm::vec2'" error. However, if I replace the variable with an actual number, the error goes away. Why does this happen and how can I fix this?
int numtriangles = sector1.numtriangles;
glm::vec2 tex[test]; //Using a variable generates an error
glm::vec3 vertices[10]; //No error here
You cannot have variable length arrays(VLA) in standard C++.
Variable length arrays are not allowed by the C++ Standard. In C++ the length of the array needs to be a compile time constant. Some compilers do support VLA as a compiler extension, but using them makes your code non-portable across other compilers.
You can use, std::vector instead of an VLA.
See this question Is there a way to initialize an array with non-constant variables? (C++)
Short answer is no you cannot directly do this. However you can get the same effect with something like
int arraySize = 10;
int * myArray = new int[arraySize];
Now myArray is a pointer to the array and you can access it like an array like myArray[0], etc.
You can also use a vector which will allow you to have a variable length array. My example allows you to create an array with a variable initailizer however myArray will be only 10 items long in my example. If you aren't sure how long the array will ever be use a vector and you can push and pop items off it.
Also keep in mind with my example that since you've dyanmically allocated memory you will need to free that memory when you are done with the array by doing something like
delete[] myArray;
Here is a little sample app to illustrate the point
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int arraySize = 10;
int * myArray = new int[arraySize];
myArray[0] = 1;
cout << myArray[0] << endl;
delete[] myArray;
}
use STL.
IF you want a variable length array you can use vectors under #include<vector>
Native c++ array donot nave variable length array.
When you declare an array with a length specifier, only constants are allowed.
Actually it's when the program is compiled that the array length is evaluated.
Note however that it's illegal in C++ to declare int test[]; like the compiler has no way to know how much space to allocate for the variable.
Without a length specifier, there is no actual memory that is reserved for the array, and you have to resort to using pointers and dynamic memory allocation:
int * test = new int[12];
// or
int * test = new int[val]; // variable works here
// and don't forget to free it
delete [] test;
Using int test[12] actually creates an array that is statically initialized once and for all to contain 12 integers at compile time.
Do not ever attempt to do delete [] test with a variable declared this way, as it's most certainly going to make your program crash.
To be precise, if the array is declared in a function, it will use space on the program stack, and if declared in a global context, program data memory will be used.
C++ doesn't support declare variable length array. So to use a array with a length you may
Assume
a big number which is highest possible length of your array. Now declare an array of that size. And use it by assuming that it an array of your desire length.
#define MAX_LENGTH 1000000000
glm::vec2 tex[MAX_LENGTH];
to iterate it
for(i=0; i<test; i++) {
tex[i];
}
Note: memory use will not minimized in this method.
Use pointer and allocate it according your length.
glm::vec2 *tex;
tex = new glm::vec2[test];
enter code here
for(i=0; i<test; i++) {
tex[i];
}
delete [] tex; // deallocation
Note: deallocation of memory twice will occur a error.
Use other data structure which behave like array.
vector<glm::vec2> tex;
for(i=0; i<test; i++){
tex.push_back(input_item);
}
/* test.size() return the current length */