Search code examples
c++arrayspointersheap-memory

Question about Structs and Dynamic Array Address


I dynamically created an array in the heap region with a data type of a struct I defined earlier. I manage this dynamic array with a pointer. The number of elements in the array is determined by the n value entered by the user.

Now, a pointer holds the address of the first element of the array. So, is the address of the first element of the array the same as the address of the struct? Do structs behave like blocks in memory?

What I want to ask is, when n=4 is entered, and a 4-element array is created, if the first element of the array takes the address of the struct, does the pointer variable I shared below hold the address of that element and, by accessing that memory region, populate it with the values written to the struct variable by the user? In other words, are they linked to the struct's address?

struct Student
{
    int studentNumber;
    string studentName;
    double studentMark;
};

int n;
cout << "How many elements will the array have?";
cin >> n;
cin.ignore();

Student* st = new Student[n];

for (int i = 0; i < n; i++) {
    
    cout << i + 1 << ". students number:";
    cin >> st[i].studentNumber;
    cin.ignore();

    cout << i + 1 << ". students name:";
    getline(cin, st[i].studentName);

    cout << i + 1 << ". students mark:";
    cin >> st[i].studentMark;

    cout << &st[i] << endl;
    cout << &(st[i].studentNumber) << endl;
}

delete[] st;

Solution

  • Memory layout

    Yes, the elements in an array are contiguous in memory, and yes, st in your code is a pointer to the first Student struct in that dynamically allocated array.

    Barring a scenario where the structs are const, yes, you can use std::cin to read information into the individual fields of the elements of this array.

    std::string

    Please note that the char array data contained with a std::string is dynamically allocated, and is thus not a contiguous part of the array's memory.

    std::vector

    As noted in comments, best practice is to use std::vector to represent arrays whose size is not known at compile-time, in large because this handles memory allocation and de-allocation for you. You also probably want to avoid using namespace std; and use a range-based for-loop.

    Something like the following.

    #include <iostream>
    #include <string>
    #include <vector>
    
    struct Student
    {
        int studentNumber;
        std::string studentName;
        double studentMark;
    };
    
    int main() {
        int n;
        std::cout << "How many elements will the array have?";
        std::cin >> n;
        std::cin.ignore();
    
        std::vector<Student> st(n);
    
        for (auto &student : st) {
            std::cout << i + 1 << ". students number:";
            std::cin >> student.studentNumber;
            std::cin.ignore();
    
            std::cout << i + 1 << ". students name:";
            std::getline(cin, student.studentName);
    
            std::cout << i + 1 << ". students mark:";
            std::cin >> student.studentMark;
    
            std::cout << &student << std::endl;
            std::cout << &(student.studentNumber) << std::endl;
        }
    }