1

I am trying to create a function in a c++ file to create an identity matrix, and return a pointer to the first element in said matrix

I have the following code, with a void print_matrix function to display the matrices

#include <iostream>

void print_matrix(int *p, int n) {
    for (int row = 0; row < n; row++) {
        for (int col = 0; col < n; col++) {
            std::cout << *p << "\t";
            p++;
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

int *get_identity_matrix(int n) {
    int m[n][n];
    for (int row = 0; row < n; row++) {
        for (int col = 0; col < n; col++) {
            if (row == col) {
                m[row][col] = 1;
            } else {
                m[row][col] = 0;
            }
        }
    }
    std::cout << "Before:" << std::endl;
    std::cout << "Address of m[0][0]: " << &m[0][0] << std::endl;
    print_matrix(&m[0][0], n);
    return &m[0][0];
}

int main() {
    int n = 3;
    int *pm = get_identity_matrix(n);
    std::cout << "After:" << std::endl;
    std::cout << "Address of pm: " << pm << std::endl;
    print_matrix(pm, n);
    return 0;
}

when compiling I get the warning: (not sure if this is useful)

src/main.cpp:27:13: warning: address of stack memory associated with local variable 'm' returned [-Wreturn-stack-address]
    return &m[0][0];
            ^
1 warning generated.

When running the code, I get the following output:

Before:
Address of m[0][0]: 0x7ff7b42ff9b0
1   0   0   
0   1   0   
0   0   1   

After:
Address of pm: 0x7ff7b42ff9b0
0   32760   1   
1   197148432   1   
197144129   32760   -1271924224

TL;DR why are these matrices different when being printed? I am passing the same values for int *p, int n each time the print_matrix function is being called

I was expecting for the print_matrix function to print the same identity matrix twice

epic pants
  • 11
  • 1
  • 2
    `return &m[0][0];` return a pointer to the first element of `m`. `m` is then destroyed as it's a local; leaving a dangling pointer. Any dereference of `pm` is Undefined Behaviour as it does not point to a valid location. You can either use `new` to allocate `m` or preferable use `std::vector< std::vector< int > >`. – Richard Critten Nov 20 '22 at 21:04
  • 2
    Does this answer your question? [How to return local array in C++?](https://stackoverflow.com/questions/7769998/how-to-return-local-array-in-c) – Richard Critten Nov 20 '22 at 21:08
  • Why are you using C-style arrays? `int m[n][n];` is non-standard, for one thing. – Paul Sanders Nov 20 '22 at 21:41

1 Answers1

0

In C++, local variables go out of scope. When they do, the memory they occupy is freed. m is a local variable in get_identity_matrix; as a result, after you return the memory address of m, the memory m occupies is freed as it goes out of scope once the function ends. Thus, you now have a pointer to a bunch of garbage memory, and when you print its values out, you get a bunch of garbage values.

Returning the memory address of a local array is generally undefined behavior. Instead, use the C++ equivalent std::array, instead of C-style arrays.