3

I created a program that prints 2 dimension matrix from external txt file. My program works if I define static matrix such as A[10][10]. But I want to allocate memory dynamically.

When I try this code:

int **A = (int **)malloc(N * N * sizeof(int));

There is error as following:

Unhandled exception at 0x00AC159B in dataStructures4.exe: 0xC0000005: Access violation writing location 0xCDCDCDCD.

On this loop:

for(i=0; i<N; i++){
    for(j=0; j<N; j++){
        A[i][j] = -1;
    }
}

I think I can't generate dynamic matrix correctly. How should I modify my code?

2

6 Answers 6

8

You dynamically create 2d arrays as a pointer to chunk of int* pointers which point to a chunk of ints.

So there are two steps:

1) A to point to the first of a chunk of int*

int **A = (int **)malloc(N * sizeof(int*));

2) each of them to point to the first of a chunk of ints

for(i=0; i<N; i++){
    A[i] = (int *)malloc(N * sizeof(int));
}
Sign up to request clarification or add additional context in comments.

Comments

5

Use a pointer to an array of specific size:

You can use #define to define N, or use a variable:

int n = 10 ;
int (*A)[n] = malloc(n * n * sizeof(int));

This way you get a contiguous block of memory.

13 Comments

Too bad that N in int (*A)[N] must be known at compile time. This is not what he wants.
@FilipeGonçalves No, you are wrong. You can do than no problem ( at least from c99 forward ). My proof( don't have time to search specs ) ideone.com/bW4Qeo
Sorry, my bad. Nice answer. I know C99 allows VLAs, I just wasn't thinking. +1
Ok then, but why wouldn't he use a 2D VLA in the first place?
@self. Your answer surely makes use of VLAs. A is a pointer to a variable length array. If the compiler doesn't support VLAs, which seems to be the case, this won't work.
|
1

Remember that A[i][j] is the same as *(*(A+i)+j). Your code is broken because *(A+i) dereferences an invalid, uninitialized pointer. This happens on this line:

A[i][j] = -1;

The alternative is to use a dynamically allocated array of pointers, where each element points to another dynamically allocated array. You can do it like this:

int **array = malloc(N*sizeof(*array));
for (int i = 0; i < N; i++)
    array[i] = malloc(N*sizeof(*array[i]));

/* Use array[i][j]... */

Note that the memory layout is very different from that of a 2D array, but the expression array[i][j] will do what you want - it will "look" like you have a 2D array.

Comments

1

Allocate each row separately, like here:

int **A = (int **)malloc(N * sizeof(int*));

for(i=0; i<N; i++){
    A[i] = (int *)malloc(N * sizeof(int));
}

Comments

1

Same as an array, a 2 dimension matrix holds a contiguous address space. So theoretically there is a way to achieve this.

int m = 2;
int n = 4;
int *a = malloc(m*n*sizeof(int));
int **b = malloc(m*sizeof(int*));
for(int i=0, i<m, i++)
{
    b[i] = a+i*n;
}

In this manner, b can be used as a matrix as you demand. However, it will waste malloc(m*sizeof(int*)) to hold b.

or you can:

int m = 2;
int n = 4;
int *a = malloc(m*n*sizeof(int));

use a[m*i+j] as a[i][j]

Comments

0

Hope the below stuff is good. I haven't tested it, just providing you with syntax.

int** abc; // Your 2D array pointer abc[N][M]

abc = (int**)malloc(dim1_max * sizeof(int*)); // dim1_max is N
for (int i = 0; i < dim1_max; i++) {
  abc[i] = (int*)malloc(dim2_max * sizeof(int)); // dim2_max is M
}

[....your array used....]
//Once you allocate dynamically you need to free the memory. IMP point.
for (int i = 0; i < dim1_max; i++) {
  free(abc[i]);
}
free(abc);

Comments

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.