pointer

YoungJoon Suh·2023년 7월 9일
post-thumbnail

int ptr;
double
ptr2;

ptr can point to an int value.
ptr2 can point to a double value.

The statement ptr = # assigns the address of variable num to pointer variable ptr.
Make ptr point to the value of variable num.

It is a serious runtime error to dereference a pointer whose current value is nullptr. Your program will abort (abruptly terminate).

So far, all our variables have names and are created automatically when we declare them: int num;

We can also create nameless variables.
The new operator returns a pointer to the variable it just created.
This is idea for pointer variables.
int *ptr = new int(42);

If your program creates nameless variables, then it must remove them from memory when the program no longer needs them.
Delete from memory the nameless variable that ptr points to. delete ptr;
This will not set ptr to nullptr.
Attempting to access deleted memory is a serious runtime error that can abort your program.

Memory Leaks
If your program doesn't get rid of all the nameless variables it created, those variables clutter up memory, and therefore you are said to have a memory leak.

We can pass a pointer by value to a function.
void foo(int ptr1, double ptr2);
In the function, we can change the value of the variable that ptr1 points to. The value of ptr1 itself does not change.
We can also pass a pointer by reference.
void bar(int &ptr1, double &ptr2);
Now in the function, we can also change what variable ptr1 points to. Ugly syntax!

Use typedefs to simplify pointer notation:
typedef int IntPtr;
typedef double
DoublePtr;

Now you can use IntPtr in place of int and DoublePtr in place of double.
void foo(IntPtr ptr1, DoublePtr ptr2);
void bar(IntPtr& ptr1, DoublePtr& ptr2);

Using Pointers to Pass-by-Reference
C programmers used pointers to pass parameters by reference.
Example: function baz(int parm);
A call to the function needed the address of the corresponding argument:
int arg;
baz(&arg);
Because parm points back to the actual argument, the function can use
parm to change the value of the actual argument (arg in this example).
An array variable is actually a pointer variable.
The array/pointer variable points to the first element of the array.
Up until now, whenever we declared an array, we explicitly gave its size.
Example: int a[10];
But suppose we don't know until run time how many elements we need.
Example: At run time, your program reads in a count of names, and then the names. You want to create an array that can hold exactly that many names.

You can use a dynamic array (instead of a vector).

If the size of the array you want is in variable n whose value you don't know until run time, use the new operator to create an array of size n.

Use a pointer variable to point to the first element of the synamic array.
string *names = new string[n];

When you're done with the array, use the special form of the delete operator to remove the array from memory:
delete[] names;

A two-dimensional dynamic array is a dynamically allocated one-dimensional array of pointers, each of which points to the first element of a dynamically allocated one-dimensional dynamic array of values.
Think of each array of values as a "row" and therefore each element of the array of pointers points to the first element of a row.
The rows can all have the same length, or have different lengths.

Variable rows is a pointer to a one_dimensional array of pointers to integers, each of which is a pointer to a one-dimensional array of integer values.

#include
#include
using namespace std;

int make_multi_table(int row_count, int col_count);
void print_table(int
rows, int row_count, int col_count);
void delete_table(int **rows, int row_count, int col_count);

int main()
{
int **table = make_multi_table(3, 4);

print_table(table, 3, 4);
delete_table(table, 3, 4);

return 0;

}

int make_multi_table(const int row_count, const int col_count)
{
// Dynamically allocate an array of pointers to integers.
int
rows = new int*[row_count];

// For each pointer to integer ...
for (int r = 0; r < row_count; r++)
{
	// ... dynamically allocate a row of integers.
    rows[r] = new int[col_count];
    
    // For each element of a row ...
    for (int c = 0; c < col_count; c++)
    {
    	// ... calculate its value.
        rows[r][c] = (r+1) * (c+1);
    }
}

// Return the pointer to a pointer to an integer.
return rows;

}

void print_table(int *rows, const int row_count, const int col_count)
{
// For each row of the table ...
for (int r = 0; r < row_count; r++)
{
// ... get the pointer to the row of integers.
int
row = rows[r];

    // For each element of a row ...
    for (int c = 0; c < col_count; c++)

{
// ... print it.
cout << setw(3) << row[c];
}
cout << endl;
}
}

void delete_table(int **rows, const int row_count)
{
for (int r = 0; r < row_count; r++)
{
delete[] rows[r];
}
delete[] rows;
}

Recall that C programs didn't have C++ style strings, but instead had arrays of characters.
The declaration char *cstr; is for a dynamic character array, a C-string.
If you have a dynamic array of C-strings, you need a pointer to a pointer of characters.
char **cstr_array;

Instead of C-strings, use C++ strings.
Instead of dynamic arrays, use C++ vectors.
A vector has a dynamic array hidden inside of it.
The vector manages the dynamic array for you.

profile
저는 서영준 입니다.

0개의 댓글