0

I tried a lot of things to do but it still show me the same, that there is unhandled exception: access violation writing location in VS. But it doesn't happen when i sorting 1d array. What can I try next?

int main(void) {
   static int a[3][4]{}, ab[3][4]{};
   int i, j, k, N, M;
   int* a1=nullptr;
   printf("Matrica mora da ima velicinu 3 sa 4\n");
   printf("Enter the order \n\n\t");
   scanf_s("%d%d",&N ,&M);
 for (i = 0;i < M;++i)
{
    for (j = 0;j < N;++j)
    {
        scanf_s(" %d", &a[i][j]);
        ab[i][j] = a[i][j];
    }
    printf("\n");
}

for (i = 0;i < M;++i) {

    for (j = 0;j < N;++j) {

        printf(" %d", a[i][j]);

    }

    printf("\n ");
}
    
//classic sorting
for (i=0; i < M; ++i)
{
    for (j = 0;j < N;++j)
    {
        for (k = j + 1;j < N;++k)
            if (a[i][j] > a[i][k])
            {
                *a1 = a[i][j]; // there is exception thrown
                a[i][j] = a[i][k];
                a[i][k] = *a1;
            }
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186

1 Answers1

0

First off, there is a problem with static allocation of arrays, but there is no sanitization of N and M after the user inputs them. That means that you allocate only a matrix of 3x4, but the user can input and write to a matrix of any dimensions (e.g. 10x10), which could lead to access violation.

I'd recommend either having sanitation of the input values, e.g.

// It's always better to have limits as constant.
const int MAX_N = 3;
const int MAX_M = 4;
static int a[MAX_N][MAX_M];
...

scanf_s("%d%d",&N ,&M);

// Check if the dimensions can be fitted into the statically allocated array.
if(N > MAX_N || N <= 0 || M > MAX_M || M < 0)
{
    // indicate invalid dimensions, either by returning from main with -1
    // or calling exit(-1), or throwing an exception.
    return -1;
}

In case the input didn't exceed 3x4, another thing that could be problematic - i goes from 0 to M, not N (what I would expect), which could also be problematic. The way matrix addressing works in C/Cpp is that the matrix is linearized into an array, and accessing it with a[i][j] leads to accessing the array with a[i*MAX_J + j]. In your case, the array has 12 elements (3x4), and MAX_J=4, so accessing it with a reverse set of indexes a[4][3] will access a[4*4+3]=a[19], which will access memory from outside of the array.

On the access violation writing problem, a1 isn't allocated, so when you try do execute *a1= ... you are writing to nullptr, which is a protected address, hence the access violation when writing. The way to solve this is either to:

  • have a1 be a int variable (not a pointer)
  • first allocate memory for a1 by executing a1 = malloc(sizeof(int)); and then freeing it after use with free(a1) (but since it's only a single element, I'd recommend converting a1 to int instead)
  • assign the address of the matrix element like a1=&a[i][j], but that would not be valid logically in your case (after that, you write into the location the pointer is pointing to, so the original value will be lost).

The reason why it's not happening for the 1d array is probably because of the inverted dimensions - the matrix would probably be 1x4, but you will be accessing it as 4x1, and you are sorting all the values with j index from 0 to 1, and since there is only one value you would not enter the k loop.

np_6
  • 514
  • 1
  • 6
  • 19
  • 1
    In C you commonly don't cast the `void*` result of malloc to the target type. And are you aware that you can [edit] our answer, please don't add new stuff as a comment. – the busybee Apr 04 '21 at 12:55