简体   繁体   中英

Custom Function with array input printing wrong result in certain cases?

I needed to make a function that takes an array as input (and its dimensions X,Y or ROW,COL)
and calculates the sum of all lines (storing each sum in a cell of the new array.
For an input of NxN array seems to be working perfectly.
For an input of KxN array where K>N seems to be working perfectly.

int* linesum(int *ar,int X,int Y)
{
    int i,j,lsum=0;
    int *new=malloc(X*sizeof(int));
    for(i=0;i<X;i++){
        for(j=0;j<Y;j++){
           lsum+=*(ar+i*X+j);
        }
        *(new+i)=lsum;
         lsum=0;
     }
     return new;
}
lsum+=*(ar+i*X+j);

should be

lsum += *(ar+i*Y+j);

or

lsum += *(ar+i+j*X);

The difference between these two is the chosen memory layout. i counts the current row, while j counts the current column. There are now two possible (simple) memory layouts for the matrix (assume X=3 and Y=4 as an example):

0 1  2  3
4 5  6  7
8 9 10 11

or

0 3 6  9 
1 4 7 10
2 5 8 11

where numbers are the indexes of the linear array storing the matrix elements. In the first case you get the the next element of a given row by simply adding 1 , but you need to jump 4 (the number of columns Y ) to get to the next row.

In the second case you need to jump X=3 (the number of rows) to get to the next element in a given row, but if you want to get to the next row, you simply have to add 1 .

These two layouts give you the two different pointer arithmetics shown above. You decided the layout when you initialized your array, which you haven't posted, so I cannot know which one is correct in your case.

Note that from a performance viewpoint (if your matrix is very large) the first case is better for your particular access pattern, because the array can be read element by element, while the second layout would require repeatedly jumping Y elements in memory.

You could also use double arrays / pointers to get around such pointer arithmetic. Also I guess it would be good to avoid new as a variable name, even if this is C. If somebody would try to compile your code with a C++ compiler it would throw errors, because new is a reserved keyword there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM