What is the reason to get voilation of location error in this code?

-3
#define n 100      
struct array {
            int *a1;
            int *a2;
            int *a3;
            int *flag;
            int size;
        } s;

        int main()
            {

            struct array *p;
            s.size = n * sizeof(int);
            p = (struct array*) malloc(s.size);

            for (int i = 0; i < n; ++i)
                {
                    (*p).a1[i] = 9;
                    (*p).a2[i] = 5;
                }

                vector_add();

              /* print addition vector C */
              printf("\n\nAddition vector:\n");

              for (int i = n - 10; i < n; ++i)
              {
               printf("%d\t+%d\t=%d\n", s.a1[i], s.a2[i], s.a3[i]);
              }
              free(p);
              getch();

            }

When i run this code I get Exception thrown at 0x00007FF775221895 in test.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF. for line (*p).a1[i] = 9;

Can anyone point me out what is the reason to get this exception.

c
arrays
exception
memory-management
malloc
asked on Stack Overflow Dec 6, 2018 by RAJ • edited Dec 9, 2018 by RAJ

2 Answers

2

The variable s is an uninitialized global variable. That means it will be zero initialized by the system. That in turn means all members of the structure will be zero or NULL (for pointers).

That means malloc(s.size) will allocate zero bytes. It's implementation-defined if that will return a NULL pointer, or a valid pointer to memory that can be passed to free but can't be dereferenced.

Since you dereference p you will have undefined behavior in either case.

Also, you never make the pointers in the structure point anywhere valid, which means that all pointers in the structure pointed to by p would be indeterminate (and seemingly random), and dereferencing them will also lead to undefined behavior.

There's also the problem that p is supposedly pointing to a brand new instance of the structure, a distinct and separate object from s. That means your vector_add function, which I guess is working on the global s object, don't have any idea about the object that p might point to (unless you make p point to s).


The solution to your problems is four-fold:

  1. Don't declare the variable s, it's simply not needed (IMO).

  2. Don't allocate memory dynamically for p, just define it as an instance of the structure.

  3. Either allocate memory for the pointer members to point to, or use arrays instead.

  4. Pass the structure object to the vector_add function.

In code it would be something like this:

struct array
{
    int *a1;
    int *a2;
    int *a3;
    int size;
};

int main()
{
    struct array p;  // Not a pointer

    // Set the size to the number of elements
    // (TODO: Need to specify X somewhere, or read it from user)
    p.size = X;

    // Allocate memory enough for p.size number of elements
    p.a1 = malloc(p.size * sizeof *p.a1);  
    p.a2 = malloc(p.size * sizeof *p.a2);
    p.a3 = malloc(p.size * sizeof *p.a3);

    // Initialize the arrays to be added
    for (size_t i = 0; i < p.size; ++i)
    {
        p.a1[i] = 9;
        p.a2[i] = 5;
    }

    // Pass a pointer to p, and the function uses its a1, a2  and a3 members
    vector_add(&p);

    // Print the result
    for (size_t i = 0; i < p.size; ++i)
    {
        printf("%d + %d = %d\n", p.a1[i], p.a2[i], p.a3[i]);
    }

    // And finally free the memory we have allocated
    free(p.a3);
    free(p.a2);
    free(p.a1);
}
answered on Stack Overflow Dec 6, 2018 by Some programmer dude • edited Dec 6, 2018 by Some programmer dude
1

size member of struct array is uninitialized. As s is a global variable, size will be initialized to zero. So you are not allocating any memory at all in the below statement.

p = (struct array*) malloc(s.size);

So deferencing p which is undefined behavior has (in this case) led to an exception in the below statement.

(*p).a1[i] = 9;

Also, the members a1, a2 and a3 are not allocated any memory. You have to allocate memory to them as well if you want to use them.

answered on Stack Overflow Dec 6, 2018 by P.W • edited Dec 6, 2018 by P.W

User contributions licensed under CC BY-SA 3.0