4

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.

  1. 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!

9
  • I should probably ask a clear question. Sorry. Is it possible to make the equivalent of an array using pointers? If not, why not? Why is my code flagging a segmentation fault? Commented Dec 4, 2015 at 20:50
  • A dynamically allocated array is still an array. I think your intended solution (easily corrected to work) is what your teacher had in mind. But strictly speaking you would have to use e.g. a binary tree in order to avoid using an array. Commented Dec 4, 2015 at 20:53
  • It is quite possible. See all three answers below. Commented Dec 4, 2015 at 20:54
  • 1
    Using a lot of salary_pointer + i in there. Save yourself some trouble and store it. int* curp = salary_pointer + i; and after that work with *curp. Compiler should be smart enough that it will be no faster, but you may find it a bit easier on the eyes. Commented Dec 4, 2015 at 21:34
  • 1
    @user4581301: That's much of what references are about. I.e., rephprased, “Save yourself some trouble and store it. int& cur = salary_pointer[i]; and after that work with cur”. ;-) Commented Dec 4, 2015 at 21:55

4 Answers 4

9

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).

Sign up to request clarification or add additional context in comments.

3 Comments

It looks like the original code was using integer division, in which case it would be correct for the solution code to do the same.
Thank you! That cleared this right up! I noticed the integer division here as well, but I didn't write the code, my prof did. I wanted to change only the pieces in which his code had arrays.
@JoeyC. If any of the answers here addressed your issue, you should accept it one of them. It let the other users know that the issue was resolved, and it is also a courtesy for the ones that put effort into responding question on StackOverflow.
1

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.

3 Comments

What errors are those? Other than not including obvious things like #include <iostream> or using namespace std; I see no issues and neither does my compiler.
@soulsabr Something compiling does not mean it is bug free. The specifics on how to allocate, iterate through, and delete are mentioned in other answers to the original question. One example, is "new int" rather than "new int[20]"; While it compiles, it is not what the author wants, and is a bug.
@Christopher Pisz I see now. When you said he you were referring to Joey C. In that case then I agree that Joey have a major error in his code.
0

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.

2 Comments

Oh, sorry. I didn't say he was wrong. I said, I think he wrote the problem down wrong. The only thing we have discussed up to this point is how to iterate through an array. I just think it's likely he didn't mean to write the problem this way. Although, it's possible he was stretching our logical muscles a bit as well.
When in school don't expect to be spoon fed. The question at hand is a good one and from what I can see I'd imagine he means it just as he wrote it. In asking you to take the initiative to learn something before it is discussed he's assuring that you are more likely to learn the lesson. A further boon is that you'll learn other lessons looking up how to do the answer.
-1

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

8 Comments

float *salary = int[N]; What?
float *salary = new int[N]; Still nonsense.
And this is a great example of how you should NEVER do a for loop. You should be iterating off of a size_t with the condition it is less than N. Using pointers in this manor is confusing and your future project partners/coworkers will not like you for doing it.
@soulsabr That's a little overstated. You loop through linked lists that way, for example. Yes, you wouldn't expect the same for an array but it's not as obscure as you categorize it.
@soulsabr: That is pretty much nonsense; looping using iterators is not only commonplace, but idiomatic. Yes, including over arrays. What do you think for (auto el : myArray) does? Or for (auto it = std::begin(myArray), end = std::end(myArray); it != end; ++it)? That's right — the same damn thing.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.