Homework: Making an array using pointers - c++

I have a homework problem that I'm working out. Me and some other students are pretty sure that our teacher misspoke, but maybe not. I checked through a bit of the questions here already and can't really find a way to use pointers to create what is essentially an array. The instructions read as follows.
Rewrite the following program to use pointers instead of arrays:
The code is this
int main()
{
int salary[20];
int i;
for (i = 0; i < 20; i++)
{
cout << "Enter Salary: ";
cin >> salary[i];
}
for (i = 0; i < 20; ++i)
salary[i] = salary[i] + salary[i] / (i + 1);
return 0;
}
My solution was this:
int main()
{
int* salary_pointer = new int;
for (int i = 0; i < 20; i++)
{
cout << "Enter Salary: ";
cin >> *(salary_pointer + i);
}
for (int i = 0; i < 20; ++i)
{
*(salary_pointer + i) = *(salary_pointer + i) + *(salary_pointer + i) / (i + 1);
cout << *(salary_pointer + i) << endl;
}
delete salary_pointer;
return 0;
}
It keeps flagging a segmentation fault at about salary number 13
My main purpose (because I'm almost positive my teacher wrote this down wrong) is to understand more about pointers, so any and all tips and tricks for learning these confusing things would be greatly appreciated. Thank you all!

Use
int* salary_pointer = new int[20];
instead, as you allocate 20 ints, not just one. Then, delete the dynamic array using
delete[] salary_pointer;
instead of delete salary_pointer. Be also careful here:
salary[i] / (i + 1);
If the operands are int, then you end up with truncation. Use salary[i]/(i + 1.) in case you want your result as a double (in which case you better make salary an array of doubles or a pointer to double so you don't have this issue anymore).

Your teacher did not misspeak. You have bugs in your program.
How many elements did you allocate?
How many elements are you trying iterate through and dereference?
How many elements did you free?
You're getting a seg fault, because you are dereferencing memory you did not allocate.
I'd be more specific, but giving too much away won't help you get better when it comes to homework.
This kind of manual memory management is done away with later when you will be using STL containers for the most part, but the relationship between pointers and arrays, and the ability to do pointer arithmetic is important.

Why is your teacher wrong?
Here is what is happening. You are creating a pointer to a SINGLE integer. As you iterate through your for loop what you are doing is actually overwriting memory that is possibly, and I STRESS possibly, being used by other bits of your program. This causes undefined behavior up to and including a crash.
Redo your memory allocation and your access violation should go away. Also, use a variable to hold your '20'. Something like const int MAX_SALARIES = 20. Learn to do this as it will often save you TONS of headaches in the future.

In this statement
int* salary_pointer = new int;
there is allocated only one object of type int.
And as there is used the division operation it is better to use type float instead of int for the array.
I would suggest the following solution. It uses only pointers.
#include <iostream>
int main()
{
const size_t N = 20;
float *salary = new float[N];
^^^^^^^^^^^^^^^^^^^^^^^^^^
for ( float *p = salary; p != salary + N; ++p )
{
std::cout << "Enter Salary: ";
std::cin >> *p;
}
for ( float *p = salary; p != salary + N; ++p )
{
*p += *p / ( p - salary + 1 );
}
delete [] salary;
^^^^^^^^^^^^^^^^
return 0;
}

Related

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.

segmentation fault with pointer array

I am a getting a segment fault when trying to input data for my array of pointers. Im pretty new to coding so any help would be great. My task was to make an array of pointers then display, swap them around and than sort them
#include <iostream>
using namespace std;
float getValueFromPointer(float* thePointer)
{
return *thePointer;
}
float* getMinValue(float* a, float* b)
{
if (*a < *b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int arraySize;
cout << "Enter the array size: ";
cin >> arraySize;
float** speed = new float*[arraySize]; // dynamically allocated array
for(int i = 0; i < arraySize; i++)
{
cout << "Enter a float value: ";
cin >> *speed[i];
}
// Core Requirement 2
for (int i = 0; i < arraySize; i++)
{
float value = getValueFromPointer(*speed+i);
cout << "The value of the element " << i << " is: ";
cout << value << endl;
}
//float *pointerToMin = getMinValue(&speed[0], &speed[arraySize - 1]);
//cout << *pointerToMin << endl;
delete [] speed;
speed = NULL;
return 0;
}
You’ve only allocated space for the outer array but you need to also allocate space for each of the internal floats.
So before calling this line:
cin >> *speed[i];
You need to first allocate space for it:
speed[i] = new float;
Your problem is that you've allocated an array of float pointers. You need to allocate an array of floats. So currently you have no memory allocated for the actual floats. If you do this, you'll allocate that memory:
float *speed = new float[arraySize];
You don't have any need for a 2D/jagged array that I can see. If you start with the code above, the compiler errors should lead you right in the direction. (Basically you will start removing * from a lot of places in your code.)
EDIT
Based on your requirement that I misunderstood, a possible approach is the following. The other answer (the one that isn't mine) makes sense in broader scenarios than this, but hopefully this is sort of another angle to think about that rather arbitrary problem you're trying to solve:
int main()
{
float *pFloats = new float[10];
float **ppFloats = new float*[10];
//assign float values and pointers to them in same loop
for (int i = 0; i < 10; i++)
{
pFloats[i] = i;
ppFloats[i] = &pFloats[i];
}
//swap two arbitrary pointers
float *pTemp = ppFloats[4];
ppFloats[4] = ppFloats[5];
ppFloats[5] = pTemp;
//print our float array
for (int i = 0; i < 10; i++)
printf("%f\n", pFloats[i]);
//print our float array *through* our pointers
for (int i = 0; i < 10; i++)
printf("%f\n", *ppFloats[i]);
delete[] ppFloats;
delete[] pFloats;
}
Ignore the hard-coded constants, etc...The point here is that I've created a contiguous memory area for the floats, and then created an array of float pointers on top of it. Note that I can sort my pointer array with zero impact on the original array. There are much smarter ways to do this, but...looks like you're learning about raw pointers, so...
Contrast with the other answer which creates jagged memory for the floats (1 at a time, on demand, not necessarily contiguous).

Returning pointer to the beginning of an array

I've strarted learning programming about a week or two ago and I made a simple function with dynamic memory allocation. It works fine (I guess... nothing crashed yet) but i wonder if there's any other way to return to the beginning of an array instead of saving it's adress to another variable.
void time()
{
int* tab, b;
int q, i;
clock_t start, stop; //time.h cstdlib
double time;
cout << "Number of elements in array: ";
cin >> q;
tab = new int[q];
b = (int) tab;
start = clock();
for (i = 0; i < q; i++)
{
tab[i] = i;
tab[i] += 50;
}
stop = clock();
czas = (double)(stop - start)/CLOCKS_PER_SEC;
cout << "Time: "<< time << endl;
tab = (int*) b;
delete [] tab;
}
No, there is no way to take a pointer and return to its "base address". There are slightly different patterns that you could use and tricks, but they're rarely worth it.
By the way, in C++, the * is "part of the name" instead of "part of the type" in a declaration. This means that int* tab, b is like int (*tab), b, and only tab is a pointer. This is why you need to cast tab to an int right now when you assign it to b. You should either do int* tab, * b or declare them individually on different lines.
This:
b = (int) tab;
Is illegal. You are storing (and later resurrecting) a pointer in an int. That won't work at all on some machines (e.g. ones where int and int* have different sizes). You should never use C-style (foo)bar casts in C++. You can simply store your pointer in another int* pointer. But in your example program you don't need to store it at all, because you never change the address inside the original pointer.
If I were to rewrite your code, I'd do this:
void time()
{
int q;
cout << "Number of elements in array: ";
cin >> q;
vector<int> tab(q);
clock_t start = clock();
for (int i = 0; i < q; i++)
{
tab[i] = i;
tab[i] += 50;
}
clock_t stop = clock();
double time = double(stop - start)/CLOCKS_PER_SEC;
cout << "Time: "<< time << endl;
}
The above does pretty much the same thing, but is simpler and safer.

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

Program declaring variables by itself

I am still a ... novice, in c++.
I don't know the name of what I am looking for but
I 've been searching a lot but can't seem to find the answer to following question:
I want to write a program that would declare demanded number of variables.
Example:
int a;
cin>>a;
Now if "a" is 5 (or any other number), I want program to declare 5 more variables,
Names do not matter but let's say...n1,n2,n3,n4,n5.
I've tried array and for loop but can't get it to work.
I got answer on Croatian forum (forum.hr) but the forum is currently offline, so I had no
time to try it out...
It was about using heap instead of stack
Thx in advance
C++ has container classes for this purpose. In particular, you want a vector:
std::vector<int> a(size);
for (int i = 0; i < a.size(); ++i)
std::cin >> a[i];
Declares a vector a of integers of some size and reads its elements, one by one.
If this is C++, the best you can do is using std::vector as it will manage the memory for you.
you can store them in an array:
int a;
cin >> a;
int *number = new int[a]; // allocate an array of size a
for (int i = 0; i < a; i++) {
number[i] = 5 + i; // set your numbers to anything here
}
delete[] number; // otherwise you have memory leak
or better use a vector:
vector<int> number(a);
// iterate with a normal for loop
for (int i = 0; i < number.size(); i++) {
number[i] = 5 + i;
}
..
// or use iterators
for (vector<int>::iterator it = number.begin(); it != number.end(); ++it) {
cout << *it << endl;
}
so you don't have to manage memory.