1

For practice, I want to define a Matrix addition of two 2-D Matrces by pulling the pointers of them. Here is the initiation

const double A[2][2]={{1,2},{3,4}};
double B[2][2]={{4,3},{2,1}};

const double* a=*A;
double* b=*B;

However, since the pointer merely points to the first element of the first array within each matrix, a=*(A+0), how can i go through every element of each Matrix? And I only wnat to use pointer as parameter here.

void D2Add(const double*, double*){
...for loop here...
}
0

3 Answers 3

2

I only wnat to use pointer as parameter here

That way you will have undefined behavior. The different sub arrays may be placed in different pages/segments in memory and Accessing an array out of bounds is not guaranteed to work. I removed the sentence trying to explain a possible pitfall when accessing a sub array out of bounds because I can't find a good description of it right now.

One way to avoid undefined behavior is to take the arrays by reference instead:

#include <cstddef>
#include <iostream>

template<std::size_t Y, std::size_t X>
void D2Add(const double(&A)[Y][X], double(&B)[Y][X]) {
    for(std::size_t y = 0; y < Y; ++y) {
        for(std::size_t x = 0; x < X; ++x) {
            B[y][x] += A[y][x];
        }
    }
}

int main() {
    const double A[2][2]={{1,2},{3,4}};
    double B[2][2]={{4,3},{2,1}};

    D2Add(A, B);

    for(auto& inner : B) {
        for(auto value : inner) std::cout << value << ' ';
        std::cout << '\n';
    }
}

Output:

5 5
5 5
Sign up to request clarification or add additional context in comments.

8 Comments

"may be placed in different pages in memory" Can you elaborate? AFAIK this is UB only because the standard says so.
@HolyBlackCat I'll see if I can find it.
If you meant adjancent pages, then it should work just like a 1D array would work. If you mean non-adjacent pages, then the standard forbids that by requiring arrays to be contiguous.
@HolyBlackCat "the standard forbids that by requiring arrays to be contiguous" - Yes, that sounds familiar too :-) I'm not sure that it should work like a 1D array even if the pages are adjacent though. Not if the compiler is required to produce code that brings the correct page in on the particular platform. I'm very unsure about this part. I'm continuing to look for the SO post I read a long time ago.
@HolyBlackCat I can't find it :-( Perhaps it was only in some comments which makes searching for it a pain. It was probably Lundin or Peter Cordes that wrote something that got me on this track - but I had no luck finding it. I've scratched that part of my answer for now.
|
1

This is a very interesting question actually.

Formally, you're indeed only allowed to access the elements of the first sub-array, and trying to access the other one would cause undefined behavior.

But practically, there's a good chance that you might be able to loop from 0 to 4, treating the arrays as 1D arrays of size 4. But I would advise against doing this if possible.

2 Comments

Cool, thank you. So this method assumes while I create the matrix ( array of arraies), the processor would normally, or tend to, allocate sub-arraries in the same memory as a 1-D array? So if my processor is full-loaded on many tasks, or the allocation does not pass by sequence, it raises error?
@Chrsi No, it's not up the processor. The sub-arrays will always be next to each other in memory, so this is not a problem. What can happen is the compiler optimizing based on the assumption that you only access the first-subarray, and then the code breaking when the assumption doesn't hold. But such optimizations are unlikely, IMO.
1

I Hope you have good understanding of how Multi-Dimensional array is laid in memory.

problem- It is not possible by just pointers until your function has a way to know dimensions of array.

As specified, we need to pass dimensions to functions as well. Since you only want to go through every element, I'll be print each element for demonstration.

void D2Add(const double* ptr, int nRow, int nCol) {
    for (int i=0; i<nRow; i++) {
       for (int j=0; j<nCol; j++) {
           std::cout << *(ptr+(i*nCol)+j) << std::endl;
       }
    }
}

8 Comments

This causes undefined behavior, even though it may work in practice.
*(ptr+(i*nRow)+j) will still access the first sub array out of bounds.
@HolyBlackCat yeah, If pointer is not pointing any Array.
@vectorX The math wasn't the problem. It's the fact that you're accessing the first sub array out of bounds that makes the program have undefined behavior (but it'll probably work on most platforms).
If there is no way for a compiler to make this distinction, the cost of making this behavior defined in the standard should be minimal (I know, that's kind of a backward argument). Gah... I can't find the post describing the potential real pitfalls by doing this.
|

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.