1

输入矩阵的第一个元素后,我收到“分段错误(核心转储)”。我知道当尝试访问不在内存中的东西时会发生分段错误,但我不明白为什么会出现此错误。

我故意使用指针,因为我正在学习指针的用法。

#include<stdio.h>
#include<stdlib.h>
void main()
{
    int i, j, m, n;
    int **p, **q, **res;
    p = (int**) malloc(10 * sizeof(int));
    q = (int**) malloc(10 * sizeof(int));
    res = (int**) malloc(10 * sizeof(int));
    printf("Enter the number of rows and columns:");
    scanf("%d %d", &m, &n);
    printf("Enter the elements of the matrix\n");
    for(i=0;i<m;i++) 
    {
        for(j=0;j<n;j++) 
        {
            scanf("%d", &(*(*(p+i)+j)));
        }
    }

    for(i=0;i<m;i++) 
    {
        for(j=0;j<n;j++)
        {
            printf("%d      ", (*(*(p+i)+j)));
        }
        printf("\n");
    }
}
4

3 回答 3

4

这是因为您实际上并没有为 or 内部的数据p分配q内存res。您为十个整数分配大小,但您应该首先分配十个整数指针,然后分配其中的数据。

所以像这样:

/* Get `m` and `n`... */

p = malloc(m * sizeof(int *));
for (i = 0; i < m; i++)
    p[i] = malloc(n * sizeof(int));

当然,其他人也必须这样做。


另外,您知道可以使用与数组相同的语法来访问这些吗?不需要指针算术或指针取消引用。只需一个简单的p[i][j]就可以了。

于 2013-08-02T12:53:58.123 回答
1

它从这里开始:

 p = (int**) malloc(10 * sizeof(int));

p应该int **

 p = malloc(10 * sizeof(int *));

现在您已经为 10 个指针分配了内存,但仍然没有用于各个整数的内存。所以添加

for( i=0; i<10; i++ )
     p[i] = malloc(10 * sizeof(int));

你可以使用&(*(*(p+i)+j)(我更愿意写&p[i][j])为 0 <= i,j < 10; 如果您使用过它们,q同样的情况也适用于res

于 2013-08-02T12:57:50.127 回答
1

代码中的各种错误。
我已经内联了对更改的评论。我已删除qres

该代码有两种变体,一种使用单个大小的内存“块”,m * n另一种使用一个大小的内存块m来保存m指向m其他大小的内存块的指针n

m * n当 m 行中的每一行的 n 为常数时,使用大小有用的单个内存“块”

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

void main()
{
    int i,j,m,n;

    /* Changed to *p. Instead of an array of arrays 
       you'll use a single block of memory */
    int *p;

    printf("Enter the number of rows and columns:");
    scanf("%d %d",&m,&n);

    /* m rows and n columns = m * n "cells" */
    p = (int*) malloc(m * n * sizeof(int));

    printf("Enter the elements of the matrix\n");

    for (i=0;i<m;i++)
    {
        for (j=0;j<n;j++)
        {
            /* the element at row i and column j is the (i * m) + j 
               element of the block of memory, so p + (i*m) + j .
               It's already an address to memory, so you don't need the & */
            scanf("%d", (p + (i*m) + j));
        }
    }

    for (i=0;i<m;i++)
    {
        for (j=0;j<n;j++)
        {
            /* same as before, but this time you have 
               to dereference the address */
            printf("%d      ", *(p + (i*m) + j));
        }

        printf("\n");
    }
}

使用一个大小的内存块m来保持m指向m其他大小的内存块的指针n
在 n 对 m 行中的每一行都是可变的(“锯齿状”数组)时很有用

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

void main()
{
    int i,j,m,n;
    int **p;

    printf("Enter the number of rows and columns:");
    scanf("%d %d",&m,&n);

    /* We will have m "rows", each element a ptr to a full row of n columns 
       Note that each element has size == sizeof(int*) because it's a ptr
       to an array of int */
    p = (int**) malloc(m * sizeof(int*));

    printf("Enter the elements of the matrix\n");

    for (i=0;i<m;i++)
    {
        /* For each row we have to malloc the space for the 
           columns (elements) */
        *(p + i) = (int*)malloc(n * sizeof(int));

        for (j=0;j<n;j++)
        {
            /* Compare the reference to the one before, note
               that we first dereference *(p + i) to get the
               ptr of the i row and then to this ptr we add
               the column index */
            scanf("%d", *(p + i) + j);
        }
    }

    for (i=0;i<m;i++)
    {
        for (j=0;j<n;j++)
        {
            /* Note the double dereferencing, first to the address 
               of the row of data
               and then to the exact column */
            printf("%d      ", *(*(p + i) + j));
        }

        printf("\n");
    }
}
于 2013-08-02T13:02:45.747 回答