I am using following code in c++
#include <iostream>
using namespace std;
int functionIs();
int main()
{
functionIs();
return 0;
}
int functionIs()
{
int value[3];
value[0] = 0;
for (int i = 0; i < 3; i++)
{
value[i] += i + 1;
}
for (int k = 0; k < 3; k++)
{
cout << "Value = " << value[k];
cout << endl;
}
return 0;
}
Output:
Value = 1
Value = 2
Value = 4197152
What is wrong?
Thank you in advance.
You need to assign a value to every element in array value. You are only giving the first element the value 0:
Value[0] = 0;
If not you add to whatever was in memory at location value[i] whit this code:
Value[i] += i + 1;
I think you are trying to add one to the previous value in the array, not add i+1 to each value in the array. Try changing the first loop to:
value[0]=0;
for (int i=1; i<3; i++) {
value[i] = value[i-1]+1;
}
Accessing uninitialised variables is undefined, as already stated in comments. The easiest to initialise all the elements of an array to zero would be
int value[3] = {};
Aside: When i going to be changing for every iteration and the element assigned is going to change every time, why use +=, you can just assign = and be done with it.
Related
I'm writing a simple program within which a dynamic array is to be created. The function that is being used to create said array is in a second .cpp file, attached as a user-made library. Unfortunatelly Visual Studio pops an error saying that the program can't use uninitialized variable. I feel like it's a really easy problem to solve, but I don't know how to get through it. Here is the code:
int main()
{
int i = 5, j = 6;
string** Array;
createDefStruct(Array, i, j);
/*for (int k = 0; k < i; k++)
{
for (int m = 0; m < j; m++)
{
Array[i][j] = "YIKES";
cout << Array[i][j] << '\t';
}
cout << endl;
}*/
deleteDefStruct(Array, i);
return 0;
}
The createDefStruct function:
void createDefStruct(string** Arr, int varAttribCount, int varCount)
{
Arr = new string * [varAttribCount+1];
for (int i = 0; i < varAttribCount+1; i++)
Arr[i] = new string[varCount];
}
How do I go about initilizing a variable?
Thank you in advance!
So the problem is that instead of returning your array from the function you passed the array into the function as parameter. This mean that the variable is uninitialised in main (even though it is initiialised in createDefStruct). Rewrite like this
string** createDefStruct(int varAttribCount, int varCount)
{
string** Arr = new string * [varAttribCount+1];
for (int i = 0; i < varAttribCount+1; i++)
Arr[i] = new string[varCount];
return Arr;
}
int main()
{
int i = 5, j = 6;
string** Array = createDefStruct(i, j);
...
In general when you want a function to return a value you use return from inside the function to return that value. When you want to pass a value into a function you use a parameter. In your createDefStruct function varAttribCount and varCount are the parameters but the array should be a return value.
I am trying to create an array of Object pointers in order to sort some data. Here is my code:
ArrayClass<Exoplanet*> exoplanets;
int count = 0;
for (int i = 0; i < exosystems.size(); ++i) {
ArrayClass<Exoplanet> *temp = exosystems.at(i)->getPlanets();
for (int k = 0; k < temp->size(); ++k) {
exoplanets.add(&temp->at(k));
}
temp->~ArrayClass();
}
//check to see if pointer array is working properly
for (int i = 0; i < exoplanets.size(); ++i) {
exoplanets.at(i)->printPlanet();
cout << endl;
}
ArrayClass<Exoplanet> *Exosystem::getPlanets(void) const
{
return planets;
}
Also the getPlanets() function is included at the end for reference. Whenever I print the planets in the last for loop, all of the exoplanet pointers point to the last exoplanet returned from the getPlanet() function the final time through the 1st for loop. I think this has something to do with exoplanets.add(&temp->at(k)), but I am not sure how to fix it. Thanks in advance
#include <iostream>
using namespace std;
int* flipArray(int input[], int n)
{
int output[n];
int pos = 0;
for (int i = n-1; i >= 0; i--)
{
output[pos++] = input[i];
}
int* p = output;
for (int k = 0; k < n; k++)
cout << *p-k << endl << endl;
return p;
}
int main()
{
const int SIZE = 5;
int firstArray[SIZE];
for (int n = 0; n < SIZE; n++)
{
firstArray[n] = n+1;
}
int* a;
a = flipArray(firstArray, SIZE);
for (int j = 0; j < SIZE; j++)
cout << *a-j << endl;
cout << endl;
cout << *a << '\t' << *a+1 << '\t' << *a+2;
return 0;
}
I am attempting to flip firstArray using a function that returns a pointer, but I am struggling to understand how accessing an index using a pointer works.
Here is why I am confused:
Within the function flipArray, the following for-loop:
for (int k = 0; k < n; k++)
cout << *p-k << ' ';
prints "5 4 3 2 1" to the console. It was my understanding that I should be accessing an element of a vector with *(p+k), not *(p-k). If I print *(p+k), "5 6 7 8 9" is printed to the console. If I print the array without pointers and using k as the index location, "5 4 3 2 1" is printed to the console.
Within my main function, however, the values of *a which is assigned pointer p from the flipArray function, I do not get the same results:
for (int j = 0; j < SIZE; j++)
cout << *a-j << endl;
prints 5
0
-1
-2
-3 to the console, and
for (int j = 0; j < SIZE; j++)
cout << *a+j << endl;
prints 5
2
3
4
5 to the console.
Further, I thought that the pointer location of *p and the pointer of location of *a should be the same! But when I print the address &p in the function, I get the location of 0x28fde0, and when I print the address of &a in the main, I get the location 0x28fedc. Of course, these were done during the same run.
Could someone tell me where I have gone astray? Thanks!
Thanks to everyone for the informative answers.
I have updated my solution, and it is now returning what I would expect it to. I have a new question about memory leaks and when pointers need to be deleted.
int* flipArray(int input[], int n)
{
int* output = new int[n];
int pos = 0;
for (int i = n-1; i >= 0; i--)
output[pos++] = input[i];
return output;
}
int main()
{
const int SIZE = 5;
int firstArray[SIZE];
for (int n = 0; n < SIZE; n++)
{
firstArray[n] = n+1;
}
int* a;
a = flipArray(firstArray, SIZE);
for (int j = 0; j < SIZE; j++)
cout << a[j] << " "; // can also be written as *(a+j), which is more prone to bugs
delete [] a;
return 0;
}
Will the pointer output be deleted when the function flipArray returns? If not, how should I delete output while also returning it? Is deleting the pointer a in my main function the same thing as deleting output, because they point to the same location?
It has been pointed out that your main problem is coming from the operator precedence. The * operator in *p - k is evaluated before the -. This means that k will be subtracted from the value of the int pointed at by p.
This is a huge pain, which is why the braces pointer[k] are commonly used. There are situations where using pointer arithmetic *(pointer + k) makes more sense, but it can be a source of bugs.
One point to note here: it is always better to use parenthesis even if you are not sure whether or not you need them.
You do have a second problem:
Here you are declaring output on the stack as a local variable, then you are returning output. When you return back to the previous stack frame, this pointer will be pointing to a decallocated buffer:
int* flipArray(int input[], int n)
{
int output[n]; // allocated on the stack
int pos = 0;
for (int i = n-1; i >= 0; i--)
{
output[pos++] = input[i];
}
int* p = output;
for (int k = 0; k < n; k++)
cout << *p-k << endl << endl;
return p; // this stack frame ends.
}
This means the contents of the buffer can be overwritten if the space the buffer is using is reallocated. Use new to allocate on the heap:
int* output = new int[n];
make sure to call delete on the pointer when you are done using it.
This bug can even present security vulnerabilities in your applications, so make sure you know when to allocate on the heap in C++.
Update:
Question: When this function returns, the array still exists in memory, and it's location is stored in the pointer a. Does returning the value output delete it? If not, will deleting the pointer a when I am done with it in the main function serve the same purpose?
When you delete the pointer, the memory pointed to that pointer is deallocated and the pointer is left dangling. A reference to a deleted pointer is pointing at memory that is technically free, which is bad. If the allocator library decides that it wants to reuse that space, your buffer, which is now in free space, will be reallocated. This means your buffer will lose all data integrity and the data inside of it cannot be trusted.
A common practice is to assign pointers to NULL when you are done using them. This way your program will crash and you will know where your bug is:
int* p = new int[10];
...
delete p;
p = NULL;
...
p[0] = 0; // this will now crash because you are accessing NULL.
for (int k = 0; k < n; k++)
cout << *p-k ;
It was my understanding that I should be accessing an element of a vector with *(p+k), not *(p-k).
Your understanding is right.You are not accessing the array here.p points to the first element 5 and every time k is substracted from it, which gives you 5-0 5-1 5-2 and so on which is equivalent to the filpped array.So if you want to access the array using the pointer
for (int k = 0; k < n; k++)
cout << *(p+k) ;// Note the paranthesis
for (int k = 0; k < n; k++)
cout << *p-k << endl << endl;
What this code is doing is completely different from what you think it does.
*p - k will be processed like
*p = 5 - 0 = 5
*p = 5 - 1 = 4
and so on not *(p+k) or *(p-k)
For your understanding :
int a[5] = { 1,2,6,4,5};
In order to access 3rd element in the array you do
a[2] = *(a+2)
and not
*a + 2
*(a + 2) = 6 and *a + 2 = 1 + 2 = 3
Take care of not returning the pointer to the local variable which will lead to undefined behavior
I'm trying to create a magic square that will print four different grid sizes (5x5, 7x7, 9x9, 15x15). The error I'm having is the array magsquare within the function tells me it needs a constant integer. (I can't use pointers) This is a class assignment.
#include <iostream>
#include <iomanip>
using namespace std;
void magicSquare(int n){
int magsquare[n][n] = { 0 }; /*THIS is the error with [n][n]*/
int gridsize = n * n;
int row = 0;
int col = n / 2;
for (int i = 1; i <= gridsize; ++i)
{
magsquare[row][col] = i;
row--;
col++;
if (i%n == 0)
{
row += 2;
--col;
}
else
{
if (col == n)
col -= n;
else if (row < 0)
row += n;
}
}
for (int i = 0; i < n; i++){
for (int j = 0; j < n; j++){
cout << setw(3) << right << magsquare[i][j];
}
cout << endl;
}
}
int main(){
int n = 5;
magicSquare(n);
return 0;
}
Indentation may look incorrect, but it's right. Sorry.
The failure is because standard C++ cannot allocate dynamically sized array on the stack, as you are trying to do.
int magsquare[n][n];
As far as magicSquare is concerned n is only known at runtime and for an array to be allocated on the stack it's size must be known at compile time.
Use a 15 x 15 array.
int magsquare[15][15];
As long as you know this is the largest you'll ever need, you should be ok.
Alternatives (which you've already said you can't use)
Use new to declare a 2d array of the required dimensions. (Remember to delete[] it though)
Use std::vector
It may also be a good idea to add a check that n values over 15 or under 1 are rejected, otherwise you'll face undefined behaviour if any values outside of 1-15 are passed into the function.
I'm trying to fill an array with numbers 1111 to 8888, with each integer in the number being between 1 and 8 in c++. However, when I run it, it's only outputting large negative numbers indicating an error. I honestly have clue what the error is so it would be appreciated if you could help me out. Thanks!
int fillArray()
{
int arrayPosition;
int guesses[4096];
arrayPosition = 0;
for (int i = 1; i <= 8; i++)
for (int j = 1; j <= 8; j++)
for (int k = 1; k <= 8; k++)
for (int m = 1; m <= 8; m++)
{
guesses[arrayPosition] = ((i * 1000) + (j * 100) + (k *10) + m);
cout << guesses[arrayPosition];
arrayPosition++;
}
return guesses[4096];
}
Your return type is wrong. int fillArray(), but you're trying to return an int[4096] that was declared on the stack... What you're actually doing with return guesses[4096]; is returning the first memory location after your array in memory, which is probably just garbage, hence your issue with large negative numbers.
You can fix it by allocating your array in the heap, and returning a pointer to the start of that array:
int * fillArray()
{
int arrayPosition;
int * guesses = new int[4096];
// other stuff stays the same...
return guesses;
}
However, since your function is called fillArray, it would make more sense to pass in an array and fill it rather than creating the array in the function. (If you wanted to do that, might call it something like make_1_to_8_array instead, to make it more clear that you're constructing something that will need to be deleted later.) Giving an int* as the first argument would allow you to pass in the base address of your array that you want filled:
void fillArray(int * guesses)
{
int arrayPosition;
// other stuff stays the same...
}
Or, if you want to verify that the you're using an array of the exact size:
void fillArray(int (&guesses)[4096])
{
int arrayPosition;
// other stuff stays the same...
}
Note that the function now returns void since you just update the array that was passed in, and you don't need to return anything new.
Your for-loops look correct, but your array handling is off, as is highlighted by other answers.
It is more usual in C++ to use std::vector and to pass this in by reference as an argument. This saves you having to handle memory allocations and deallocations. Here's an example, including the output in the for-loops:
#include <iostream>
#include <vector>
int fillArray(std::vector<int>& guesses)
{
for (int i = 1; i <= 8; i++)
for (int j = 1; j <= 8; j++)
for (int k = 1; k <= 8; k++)
for (int m = 1; m <= 8; m++)
{
guesses.push_back((i * 1000) + (j * 100) + (k * 10) + m);
std::cout << guesses.back() << std::endl;
}
return guesses.back();
}
int main()
{
std::vector<int> guesses;
std::cout << fillArray(guesses) << std::endl;
}
You are creating your array locally then attempting to return it. If you try printing (to debug) out the result of your array prior to returning, you will see it is ok. However, once you return, the array is no linger valid. Try passing in an array into your function instead.