Адреса совпадают (указатели, программирование на C) - PullRequest
2 голосов
/ 10 января 2012

У меня есть два двумерных массива, и я не знаю, почему или как адреса двух элементов, по одному из каждого массива, совпадают ... Вот исходный код:

#include <stdio.h>

int main()
{
    int i,j,m,n,o,p,*ptr;
    printf("Enter dimension of 1st matrix: ");
    scanf("%d * %d",&m,&n);
    printf("Enter dimension of 2nd matrix: ");
    scanf("%d * %d",&o,&p);
    int *a[m][n];
    int *b[o][p];
    if (n!=o) return 0;

    printf("\nEnter 1st matrix:\n");
    for (i=0;i<m;i++)
        for (j=0;j<n;j++)
        {   printf("%d   ",(a+i*(n-1)+i+j)); scanf("%d",(a+i*(n-1)+i+j));   }

    printf("\nEnter 2nd matrix:\n");
    for (i=0;i<o;i++)
        for (j=0;j<p;j++)
        {   printf("%d   ",(b+i*(p-1)+i+j)); scanf("%d",(b+i*(p-1)+i+j));   }

    /*Printing the matrices*/
    puts("");puts("");
    for (i=0;i<m;i++)
        {for (j=0;j<n;j++)
            {   ptr = (a+i*(n-1)+i+j);
                printf(" %d ",*ptr);    }   puts("");}puts("");
    for (i=0;i<o;i++)
        {for (j=0;j<p;j++)
            {   ptr = (b+i*(p-1)+i+j);
                printf(" %d ",*ptr);    }   puts("");}
}

Ивот экран печати; Screen print showing two coinciding adresses

Из-за этого я получаю ошибки в простой программе для вычисления произведения двух матриц.Вопрос в том, это обычно?Разве компилятор или ОС не должны были позаботиться об этом?

Кроме того, почему я должен делать ptr = (a+i*(n-1)+i+j); printf(" %d ",*ptr);?
Почему printf(" %d ",*(a+i*(n-1)+i+j)); не работает?

Ответы [ 4 ]

6 голосов
/ 10 января 2012

Прежде всего, a и b являются массивами указателей, и указатели никогда не инициализируются.

int *a[m][n];
int *b[o][p];

Я предполагаю, что он должен был прочитать:

int a[m][n];
int b[o][p];

(Остальной код необходимо будет соответствующим образом изменить.)

Во-вторых, вы рассматриваете указатели как ints (например, в %d).Имейте в виду, что указатель может быть шире int.Например, на моей платформе указатели являются 64-разрядными, а ints - 32-разрядными.

1 голос
/ 10 января 2012

Я видел несколько проблем, поэтому переписал программу следующим образом:

#include <stdio.h>
#include <stdlib.h>

void display(int **matrix, int r, int c)
{
    int i, j;
    for (i=0 ; i<r ; i++) {
        for (j=0 ; j<c; j++) {
            printf("%3d  ", matrix[i][j]);
        }
        printf("\n");
    }
    return;
}

int main(void)
{
    int r1, c1, r2, c2;
    int **matrix1, **matrix2;
    int i, j;

    printf("Enter r1: ");
    scanf("%d", &r1);
    printf("Enter c1: ");
    scanf("%d", &c1);

    if ((matrix1 = (int **) malloc (sizeof(int *) * r1)) == NULL) {
        printf("unable to allocate memeory \n");
        return -1;
    };
    for (i=0 ; i<r1 ; i++) {
        if ((matrix1[i] =  malloc (sizeof(int) * c1)) == NULL) {
            printf("unable to allocate memory \n");
            return -1;
        }
    }

    printf("Enter contents of matrix 1\n");
    for (i=0 ; i<r1 ; i++) {
        for (j=0 ; j<c1; j++) {
            printf("matrix1[%d][%d] :", i, j);
            scanf("%d", &matrix1[i][j]);
        }
    }

    printf("Enter r2: ");
    scanf("%d", &r2);
    printf("Enter c2: ");
    scanf("%d", &c2);

    if ((matrix2 = (int **) malloc (sizeof(int *) * r2)) == NULL) {
        printf("unable to allocate memeory \n");
        return -1;
    };
    for (i=0 ; i<r2 ; i++) {
        if ((matrix2[i] =  malloc (sizeof(int) * c2)) == NULL) {
            printf("unable to allocate memory \n");
            return -1;
        }
    }

    printf("Enter contents of matrix 2\n");
    for (i=0 ; i<r2 ; i++) {
        for (j=0 ; j<c2; j++) {
            printf("matrix1[%d][%d] :", i, j);
            scanf("%d", &matrix2[i][j]);
        }
    }

    printf("Contents of matrix 1 is as follows \n");
    display(matrix1, r1, c1);
    printf("\n\n");
    printf("Contents of matrix 2 is as follows \n");
    display(matrix2, r2, c2);

    /* now, free the contents of the matrix 1 and 2 */

    for (i=0 ; i<r1 ; i++) 
        free(matrix1[i]);
    free(matrix1);

    for (i=0 ; i<r2 ; i++) 
        free(matrix2[i]);
    free(matrix2);

    return 0;
}

Вывод

$ gcc 2d.c 
$ ./a.out 
Enter r1: 2
Enter c1: 2
Enter contents of matrix 1
matrix1[0][0] :1
matrix1[0][1] :2
matrix1[1][0] :3
matrix1[1][1] :4
Enter r2: 5
Enter c2: 6
Enter contents of matrix 2
matrix1[0][0] :1
matrix1[0][1] :2
matrix1[0][2] :3
matrix1[0][3] :4
matrix1[0][4] :5
matrix1[0][5] :6
matrix1[1][0] :7
matrix1[1][1] :8
matrix1[1][2] :9
matrix1[1][3] :0
matrix1[1][4] :1
matrix1[1][5] :2
matrix1[2][0] :3
matrix1[2][1] :4
matrix1[2][2] :5
matrix1[2][3] :6
matrix1[2][4] :7
matrix1[2][5] :8
matrix1[3][0] :9
matrix1[3][1] :0
matrix1[3][2] :1
matrix1[3][3] :2
matrix1[3][4] :3
matrix1[3][5] :4
matrix1[4][0] :5
matrix1[4][1] :6
matrix1[4][2] :7
matrix1[4][3] :8
matrix1[4][4] :9
matrix1[4][5] :0
Contents of matrix 1 is as follows 
  1    2  
  3    4  


Contents of matrix 2 is as follows 
  1    2    3    4    5    6  
  7    8    9    0    1    2  
  3    4    5    6    7    8  
  9    0    1    2    3    4  
  5    6    7    8    9    0  
$  

Примечания:

  • при полученииrows и columns от пользователя, лучше использовать функции динамического выделения памяти, такие как malloc(), для соответствующего распределения памяти
  • Ваш способ доступа к ячейке массива, такой как (a+i*(n-1)+i+j), слишком сложен.При работе с указателями / массивами хорошо поддерживать простоту.Пожалуйста, попробуйте придерживаться a[][] способа доступа к местоположению массива.
0 голосов
/ 11 января 2012

Как уже упоминалось выше, вы, вероятно, хотите сделать a и b int [] [] вместо int * [] []. Кроме того, вы не должны писать a+i*(n-1)+i+j), но &a[i][j] или *(a+i)+j. (или другой комбайн, например a[i]+j). компилятор должен автоматически преобразовать адрес в правый член массива.

(извините за мой плохой английский)

p.s. В любом случае, почему вы написали i*(n-1)+i, а не просто (но, как я писал выше, тоже неправильно) i*n?

0 голосов
/ 10 января 2012

Думаю, проблема в том, что a и b являются указателями на указатели на указатели на int (int [] [] []), но ваш код использует их так, как если бы они были указателями на указатели на int (int [] []).Из-за этого, даже если массивы были размещены правильно (что не так), их адреса могут храниться близко друг к другу, вызывая это неожиданное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...