-3

Does anybody know why visual studio throws me an exception when i want to compare an element of the matrix with 0?

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

#define DIM 100

void citire(int **a, int n);
int negNumbers(int **a, int n);

void main(void)
{
    int *a, n,nn;
    printf("n = ");
    scanf("%d", &n);
    citire(&a, n);

    nn = negNumbers(&a, n);
    printf("\nThe negative numbers are : %d", nn);
    _getch();
}

void citire(int **a, int n)
{
    *a = (int *)malloc(sizeof(int)*n*n);
    for (int i = 0; i < n*n; i++)
            scanf("%d", *a+i);

}

int negNumbers(int **a, int n)
{
    int k = 0;
    *a = (int *)malloc(sizeof(int)*n*n);
    for (int i = 0; i < n-1; i++)
        for (int j = i; j < n; j++)
        {
            if (*(*(a + i) + j) < 0)
                k++;
        }
    return k;

}

This is all the code. It throws me this exception:

0xC0000005: Access violation reading location 0xCCCCCCD0.

I have to mention that if I use the debugger the result is good.

underscore_d
  • 6,309
  • 3
  • 38
  • 64
TheMole
  • 11
  • 3
  • What exception? [Edit] your question to quote it in full. Also, post the code that calls `negNumbers()` and causes the exception. – underscore_d Dec 14 '17 at 15:09
  • 5
    You allocate a contiguous chunk of memory for the whole matrix but access it as if it were an array of arrays. And it's uninitialized, there's nothing to compare. – tkausl Dec 14 '17 at 15:10
  • You don't initialize the memory you allocate, so its contents will be *indeterminate*. What use is it to compare indeterminate and unknown and seemingly random data with anything? – Some programmer dude Dec 14 '17 at 15:11
  • you should check to see if a is allcocated – Nevado Dec 14 '17 at 15:11
  • _"I have to mention that if I use the debugger the result is good."_ Well, that just indicates undefined behaviour, which you get by reading uninitialised memory, which you somehow think you can do. In debug mode, probably that memory is initialised for you, but that means nothing; the code is still wrong. Also: `#define _CRT_SECURE_NO_WARNINGS` is probably a bad idea given that you seem to be prone to writing woefully nonsensical and insecure code without thinking about it. – underscore_d Dec 14 '17 at 15:14
  • 1
    [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Lundin Dec 14 '17 at 15:17

1 Answers1

3

As pointed out in a comment, this:

if (*(*(a + i) + j) < 0)

access makes no sense at all. It doesn't match the actual contents of *a at all (which is a single pointer to n * n integers).

It should be:

(*a)[i * n + j]

Or do away with the double star pointer internally for clarity's sake and just have a local pointer while accessing inside the function:

int * const base = malloc(n * n * sizeof *base);

is how I would write it.

Then access like so:

base[i * n + j] = ...

Then of course don't forget to export it to the caller at the end:

*a = base;

Also, since all the memory is uninitialized coming straight from malloc(), the code makes ... no sense.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Isn't the double-pointer necessary so that the malloc'd matrix is accessible to the calling function? – Christian Gibbons Dec 14 '17 at 15:20
  • 1
    "and I'm not sure how that manages to compile." Since `*(*(a + i) + j)` is equivalent to `a[i][j]` and `a` is an `int**` it is perfectly fine (for the compiler). – tkausl Dec 14 '17 at 15:21