0

For a problem, I have to use dynamic allocation and functions (using pointer variables only) to read the names from the .txt file and sort the names in lexical order. However, I cannot even get the read function to work properly. This is what it wrote:

void readNames(std::string* a[])
{
    std::ifstream fin; 
    fin.open("names.txt");
    for (int i = 0; i < 7; ++i)
    {
        fin >> *(a[i]); 
        std::cout << *a[i];
    }
}

This is how I called it in main:

std::string* names;
names = new std::string[7];
readNames(&names);

However, when I run this I get the error:

Exception thrown: read access violation. this was 0xCCCCCCCC.

And this function is displayed(not sure if this helps):

 void _Check_offset(const size_type _Off) const { // checks whether _Off is in the bounds of [0, size()]
        if (_Mysize < _Off) {
            _Xran();
        }
    }

If anyone can help me with this I would relly appreciate it, thank you!

7
  • 2
    (*a)[i] in all contexts in readNames will do what you want, but passing name by address still has a pretty bad code smell. I see no reason to pass that pointer by address in the first place unless the API itself is fixed (and it certainly doesn't look like it), and frankly I'd change both the caller and function, or better still, use a vector of strings instead. Commented Oct 20, 2020 at 14:50
  • 0xCCCCCCCC means uninitialized stack memory: https://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations Commented Oct 20, 2020 at 14:54
  • The only reason I am doing it is because I think that is what the question is asking for. I included the HW question in my original question. Commented Oct 20, 2020 at 15:00
  • 1
    void readNames(std::string* a[]) would be better written (provided there are always 7 elements) as void readNames(std::array<std::string,7> & arr) or maybe std::array<std::string,7> readNames() Commented Oct 20, 2020 at 15:04
  • I think the teacher wants you to use void readNames(std::string* arr, int numElements) instead of void readNames(std::string* a[]) Commented Oct 20, 2020 at 15:20

1 Answer 1

2

To elaborate on WhozCraig's comment, let us assume the following:

  • names resides on the stack, so we give it address 0x7f001000.
  • The array of strings you allocates resides on the heap, so we give it address 0x1000
  • You assigned that address to names, so address 0x7f001000 contains the value 0x1000.

Inside readNames, a is the address of names, so the expression *(a[i]) can be rewritten as:

*(*(&names + i))

For i=0, this works out. You basically dereference a once to get the start of the array, and then again to get a reference to the first allocated std::string.

For any other i, you access data on the stack (0x7f001000 + i) and then dereference that value as a pointer to a std::string.

By writing (*a)[i] you get the following calculation instead:

*(*(&names) + i) 

which is

*(names + i)

, or

names[i]
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the comment, I really appreciate it. I have tried to change it to (*a)[i] , but I still get the same error unfortunately
@ZachSal both of them ? As I said in my comment, there are two instances of a[i] in that proc that are wrong. fin >> *(a[i]); should be fin >> (*a)[i]; and std::cout << *a[i]; should be std::cout << (*a)[i]; . If the real code is as you posted in your question, that will address the problem. If it isn't the same as posted, we're wasting our time. Botje's answer is a glorious description of how things are going wrong by using improper addressing.
Yes I changed both of them. However changing the function declaration to void readnames(std::string* s) and then fin>>s[i] worked.

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.