C++ Code Output explanation - c++

I have the following code, and the question asks me to find the output. I've found the output (2) by typing it in, but I'm having trouble figuring out how/why. Any Help?
Here's the code:
int scores[5];
int *numbers = scores;
for (int i=0; i <=4; i++)
*(numbers+i)=i;
cout << numbers[2] <<endl;

Your code essentially does
scores[2] = 2;
cout<<scores[2]<<endl;
Thus the answer..
In more detail:
int scores[5];
int *numbers = scores; //numbers points to the memory location of the array scores
for (int i=0; i <=4; i++) // as mentioned, stray ';'
*(numbers+i)=i; //same as numbers[i] = i which is same as scores[i] = i
cout << numbers[2] <<endl;

The only statement being executed by the for loop is
*(numbers+i)=i;
Which will store the index of the int element at that position using the deference operator (*).
Then you are printing out the THIRD number, which equates to 2, since arrays start at index 0.

You set a pointer to the first memory location of the array, then traverse the series of memory addresses and write to them. It should be noted that using pointer arithmetic with a dereference,
*(pointer + i) = i;
is the same as using the subscript operator:
pointer[i] = i;

Related

Garbage value when trying to remove value from dynamic array

i keep getting garbage value on one of the indexes in the dynamic array when i try to remove a value which was entered by user from a list of elements in the dynamic array.
used pointer as function parameters and replaced the value to be removed with 0 and by using a counter and for loop tried to skip all the 0s but in place of zero theres a garbage value.
#include<iostream>
#include<fstream>
using namespace std;
int size = 0;
int final = 0;
int* read(ifstream& a){
int temp;
a.open("data(1).txt");
while (!a.eof()){
a >> temp;
size++;
}
a.close();
a.open("data(1).txt");
int* arr = new int[size];
for (int i = 0; i < size; i++)
a >> arr[i];
return arr;
}
int* remove(int* a,int search){
for (int i = 0; i < size; i++){
if (a[i] == search)
a[i] = 0;
else final++;
}
int* change = new int[final+1];
for (int i = 0; i < size; i++){
if (a[i] > 0){
change[i] = a[i];
}
else continue;
}
delete[] a;
a = nullptr;
return change;
}
int main(){
int* ptr = nullptr;
int num;
cout << "please enter the number to remove: ";
cin >> num;
ifstream in;
ptr=read(in);
ptr=remove(ptr, num);
for (int i = 0; i < final; i++)
cout << ptr[i] << " ";
cout<<endl;
system("pause");
return 0;
}
There is much to discuss and critize about your code. Also your question is very unclear because we do not have your input file, nor do you tell us what the code should actually do. However, I will leave all "please write actual c++ rather than c without classes" aside and just point you to the one critical mistake:
This loop
int* change = new int[final+1];
for (int i = 0; i < size; i++){
if (a[i] > 0){
change[i] = a[i];
}
else continue;
}
And then this loop
for (int i = 0; i < final; i++)
cout << ptr[i] << " ";
It seems like you want to copy all elements that are >0 to change. Or maybe you want to copy all, its really hard to tell, because broken code is just broken, it does not explain itself. Anyhow...
The first loop leaves all elements change[i] where a[i] <= 0 uninitialized. The values at those indices i are indeterminate. There isn't really a value you can read. Attempting to read an indeterminate value results in undefined behavior.
You are attempting to read all elements of change, but some of them are not initialized, they are indeterminate values. Hence your code has undefined behavior.
There are other situations the will bring your code into bad states, like for example search not begin found in the input array or a[i] > 0 for some i > final. Though, I don't see a possiblity for any input to your code that would not eventually invoke undefined behavior.
You sould use a debugger to see where your code is doing something unexpected.

Problem outputting dynamic array from function [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
the function is to preserve argument array and produce anidentical array in the heap memory that has the even elements to (left) & odd(right), but when i output i find a row of zeros and bunch of random big numbers which look like addresses but I don't think they are, Please help.
int* even_left_odd_right(int arr[], int size1)
{
int* array;
array = new int[size1];
for(int i = 0; i < size1; i++)
array[i] = arr[i];
for(int i = 0, j =0; i < size1; i++)
{
if(array[i] % 2 == 0)
{
int temp = array[j];
array[j] = array[i];
array[i] = temp;
j++;
}
}
return array;
}
int main()
{
int size1;
cout << "Enter size of array:";
cin >> size1;
int* array1;
array1 = new int[size1];
int arr[size1];
cout << "Enter the entries in this array: ";
for(int i = 0; i < size1; i++)
cin >> arr[i];
even_left_odd_right(arr, size1);
for(int i = 0; i < size1; i++)
cout << array1[i] << " ";
delete[] array1;
return 0;
}`
The root cause of all your problems is that you do not use the return value of your function. Besides that, there are more things that should be corrected.
Additionally, we need to mention that what you are obviously learning now, dynamic memory management using new and delete and raw pointers for owned memory, is strongly discourage.
Basically: new, delete and raw pointers for owned memory should NEVER be used in C++.
It is that error prone that is has no place any more in standard C++. You even have an error with leaked memory and do not notice it. The array, that you are dynamically allocating in your function with new, is never deleted.
I know that teachers still do teach this crap, but just for explaining dynamic memory mangement from scratch. So, let's go ahead and use it for now.
You have however some additional errors.
Your function returns the partitioned data. But you never use the functions return value
You are using (for whatever reason??) a so called VLA (Variable Length Array) in int arr[size1];. This is illegal in C++. Real C++ compilers will not allow that.
You are mixing up arr and array1. In the beginning, you are creating array1. After creation, it is not initialized and will contain random values.
Then you call your function with arr and output array1 at the end. So, you will output random data. That is, what you see. Random data.
You could use the build in std::swap function. But I guess that it is prohibited by the teacher. What a shame.
You unneccessarily change the order of the entries in the array with swapping. But this does not harm
Your function simply returns a raw pointer. The outer world does not know anything about that. That is dangerous
You even do not know that arr in your function signature (int arr[]) will decay to a pointer
To quickly fix your code, we could write:
#include <iostream>
int* even_left_odd_right(int arr[], int size1)
{
int* array;
array = new int[size1];
for (int i = 0; i < size1; i++)
array[i] = arr[i];
for (int i = 0, j = 0; i < size1; i++)
{
if (array[i] % 2 == 0)
{
int temp = array[j];
array[j] = array[i];
array[i] = temp;
j++;
}
}
return array;
}
int main()
{
int size1;
std::cout << "Enter size of array:";
std::cin >> size1;
int* array1;
array1 = new int[size1];
//int arr[size1]; NOT ALLOWED in C++
std::cout << "Enter the entries in this array: ";
for (int i = 0; i < size1; i++)
std::cin >> array1[i];
int* array2 = even_left_odd_right(array1, size1);
for (int i = 0; i < size1; i++)
std::cout << array2[i] << " ";
delete [] array1;
delete [] array2;
return 0;
}
But such code should never be used in C++.
Again, I guess I understand requirements from teacher.
By the way. In C++17 you would probaly write the follwoing code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
int main() {
// Tell user, what to do: Get the number of data to operate on
std::cout << "\nEnter the number of data to operate on: ";
// Read the number of data from the user via std::cin. Check, if number is OK
if (size_t numberOfData{}; (std::cin >> numberOfData) and (numberOfData > 0)) {
// Define the vector for our original data with the size given by the user
std::vector<int> dataOriginal(numberOfData);
// And get the number of specified data from the user
std::cout << "\n\nAnd now, please enter the data\n";
std::copy_n(std::istream_iterator<int>(std::cin), numberOfData, dataOriginal.begin());
// We want to preserve the original input, so, make a copy of that vector
std::vector result(dataOriginal);
// Now partition the output as requested
std::stable_partition(result.begin(), result.end(), [](const int i) { return (i % 2) == 0; });
// Show result to user
std::copy(result.begin(), result.end(), std::ostream_iterator<int>(std::cout, " "));
}
else {
std::cerr << "\nError: Wrong input given for number of data\n\n";
}
}
Please note:
No loops
Input validation
CTAD
No function needed, everthing can be done with one statemennt

Invalid conversion error when trying to keep array from changing when called by a function

For this assignment, I need to make a sorted copy of an array the user has given values to. All of my code works as intended, except for this specific part. I need this function (sortedCopy) to print out the sorted version of their array, without actually changing the array itself. As far as I can tell, to do so I need to used a constant version of the array in the function so the prototype would be something like: int *sortedCopy(const int *array, int size), but all this does is give the error shown in the title. Specifically:
main.cpp:72:29: error: assignment of read-only location '*(array +
((sizetype)(((long unsigned int)i) * 4)))' array[i] = array[min]
and it does this error twice, except with array[min] = temp; at the end instead
This is the code used, with the relevant parts of main:
#include <iostream>
using namespace std;
int* sortedCopy(const int *array, int size) {
int i, j, min, temp;
for (i = 0 ; i < size - 1; i++) {
min = i;
for (j = i + 1; j < size; j++) {
if (array[j] < array[min]) {
min = j;
}
}
temp = array[i];
array[i] = array[min];
array[min] = temp;
}
cout << "Sorted array is: " << endl;
for(int i = 0; i < size; i++) {
cout << array[i] << " ";
}
cout << endl;
// Not sure if I need to return anything or not either
}
int main() {
cout << "Please enter the size of the array." << endl;
int arraySize;
int array[arraySize];
cin >> arraySize;
cout << "Please enter integer values until the array is filled." << endl;
for (int i = 0; i != arraySize; i++) {
cout << "Value " << (i + 1) << ": ";
cin >> array[i];
cout << endl;
sortedCopy(array, arraySize);
for (int i = 0; i != arraySize; i++) { // I want this part to print the
cout << array[i] << " "; // original array entered by the user
}
}
If I remove the const part of the function, it works totally fine, except it will print the sorted array after the function is called, instead of the original array.
Firstly, C/C++ is best read "top-down":
int arraySize;
int array[arraySize]; // arraySize is undefined here!!
cin >> arraySize;
On the second line, ArraySize, might be 1, or 0, or -1000. You haven't defined it until line 3.
Also, C++ doesn't allow you to allocate arrays of variable size (unless that size is const [ so it is known at compilation time]):
int array[4];
The above is fine. This helps the operating system know how much memory to provide for you on the stack (it needs to do this before your programme starts running).
const int arraySize = 4;
int array[arraySize];
Because the C++ compiler knows that arraySize is 4, it processes this just like the above code, so this is also fine.
So to handle arrays of genuinely variable length (length that depends on inputs), you need to first read the user inputs, then use dynamic allocation ("new", or a container that does dynamic allocation for you, like a vector).
As for the problem with "const", what I think that you need to understand here is that "const" is really just a promise from the programmer: The programmer is communicating to the compiler (and any programmers reading the code) that this data is not supposed to change. All the compiler does is check whether you keep your promise (or if you send it to another function / pointer that doesn't hold that promise). So by using "const" there is no work done being done for you to actually keep the data constant - just that it will complain if you don't do the work.
int* sortedCopy(const int *array, int size) {
Above you're flagging to the compiler that the sortedCopy function will keep the data in the array constant.
array[i] = array[min];
array[min] = temp;
And here (above) you are breaking that promise.
If you don't want to edit the original array, then the easiest solution is just to copy it before you send it to your sorting function.

C++ Find maximum element of an array USING ONLY POINTERS

I have an assignment where I have to find the max and min element of an array using only pointers. The directions say you have to use pointers for everything but didn't make it clear if you can make variables then just not use them and make pointers pointing to them or if there literally cant be one regular variable declaration in the program.
I already did the whole assignment by declaring variables then making pointers point to them but just to be safe I'm redoing it with no variables.
The only thing I'm having trouble with is making a for loop with only pointers because there is no variable set to 0 that I can make a pointer point to and get the memory address of 0 to start the counter.
I would just do this:
int i = 0;
int *counterptr = &i;
cout << "Please input the array values" << endl;
for (*counterptr ; *counterptr < 10; *counterptr += 1)
{
}
But since I cant make variable i to point to I don't know how to get the memory address of 0 to use for the pointer. This is what I have right now but I don't know what to make counterptr equal to.
float nums[10];
int *counterptr = ;
float *maxptr, *minptr, *difference;
maxptr = &nums[0];
minptr = &nums[0];
cout << "Please input the array values" << endl;
for (*counterptr ; *counterptr < 10; *counterptr += 1)
{
cin >> nums[*counterptr];
if (nums[*counterptr] > *maxptr)
{
maxptr = &nums[*counterptr];
}
if (nums[*counterptr] < *minptr)
{
minptr = &nums[*counterptr];
}
}
Any help would be appreciated thank you.
corrected program snippet given below. It can be written better, but I modified for your understanding from your code changed to work now. counterptr is a pointer within the array elements (as an iterator), *counterptr will be one of the elements, similarly *minptr and *maxptr are minimum and maximum elements whereas, minptr and maxptr are respective pointers to minimum and maximum elements within the array of floating point numbers. Hope this helps.
float nums[10];
float *counterptr;
float *maxptr, *minptr, *difference;
maxptr = &nums[0];
minptr = &nums[0];
cout << "Please input the array values" << endl;
for (counterptr = nums, counterptr < nums + 10; counterptr++)
{
cin >> *counterptr;
if (*counterptr > *maxptr)
{
maxptr = counterptr;
}
if (*counterptr < *minptr)
{
minptr = counterptr;
}
}

C++ segmentation fault array

In C++ I get a segmentation fault after telling the program how big the array should be (x).
Why is this happening and how do I fix this?
#include <iostream>
using namespace std;
int main()
{
int x;
cin >> x;
int array[x];
for (int *j=array; j; j++)
{
*j=0;
}
for (int *i=array; i; i++)
{
cin >> *i;
}
cout << array[3] << endl;
}
Your loop conditions are wrong.
for (int *j = array; j; j++)
and
for (int *i=array; i; i++)
will not stop at the end of the array, as the condition j (i) is true when traversing the array (i.e., to be false, the pointer needs to be nullptr). In fact, pointer arithmetic past the array boundary plus one results in undefined behaviour. Your stopping condition should be
i < array + x;
Moreover, variable length arrays are an extension and not support by the C++ standard. Use new[] instead to allocate memory, as #Joshua Byer pointed out.
int * array;
array= new int [x];
http://www.cplusplus.com/doc/tutorial/dynamic/
The conditions used in your loops are incorrect.
eg. for (int *j = array; j; j++) even though j will eventually reach the end of the array but will still never evaluate to false (allowing the loop to finish). On top of this it means you will iterate to past the end of the array and move into Undefined Behaviour, this is probably why you are seeing the segfault.
you either need to do the following (super gross solution!!!! also not C++ standard supported):
for (int i = 0, *j = array; i < x; i++, j++)
which will increment a counter and check the array at the same time as incrementing your pointer.
OR
USE VECTORS
std::vector is a much easier way to do what you are doing.
int arraySize;
cin >> arraySize;
std::vector<int> array(arraySize, 0);
for (int i=0; i < arraySize; i++)
{
cin >> array[i];
}
cout << array.at(3) << endl;
Here is a live example.
Within a for statement, the second expression should terminate the loop by evaluating to false. In this case however you never terminate the loop:
for (int *j=array; j; j++)
Instead do:
for (int *j=array; j < array + x; j++)
The expression array + x (by pointer arithmetic) means one element past the end of the array.
The above goes for both of the loops.