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!

ZachSal
  • 43
  • 5
  • 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. – WhozCraig Oct 20 '20 at 14:50
  • `0xCCCCCCCC` means uninitialized stack memory: [https://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations](https://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations) – drescherjm Oct 20 '20 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. – ZachSal Oct 20 '20 at 15:00
  • 1
    `void readNames(std::string* a[])` would be better written (provided there are always 7 elements) as `void readNames(std::array & arr)` or maybe `std::array readNames()` – drescherjm Oct 20 '20 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[])` – drescherjm Oct 20 '20 at 15:20
  • Okay, I changed that, but I am still getting the same error sadly. Thank you for the help though – ZachSal Oct 20 '20 at 15:29
  • You would have to show the changes for that, however I think you should not do that in this question because to me it would be a different question not really related to the original question which is answered. – drescherjm Oct 20 '20 at 15:34

1 Answers1

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]
Botje
  • 26,269
  • 3
  • 31
  • 41
  • 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 Oct 20 '20 at 15:15
  • 1
    @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. – WhozCraig Oct 20 '20 at 15:29
  • Yes I changed both of them. However changing the function declaration to void readnames(std::string* s) and then fin>>s[i] worked. – ZachSal Oct 20 '20 at 15:58