C程序抛出运行时错误

时间:2016-10-20 16:31:24

标签: c arrays pointers

#include<stdio.h>
#include<stdlib.h>
int main()
{
int i,j,k,n,q;
scanf("%d%d%d",&n,&k,&q);
int *m=malloc(5*sizeof(int));
int **a=malloc(20*sizeof(int));
//int a[10][10],m[10];
for(i=0;i<k;i++)
  a[i]=malloc(sizeof(int));
for(i=0;i<n;i++)
   {scanf("%d",&a[0][i]);}
for(i=0;i<q;i++)
   {scanf("%d",&m[i]);}
for(i=0;i<k;i++)
{
   for(j=0;j<n;j++)
   {
       if(j==(n-1)) a[i+1][0]=a[i][j];
            else
        a[i+1][j+1]=a[i][j];
    }

}
for(i=0;i<q;i++)
printf("%d\n",a[k][m[i]]);
return 0;
}

我在代码块中尝试了此代码,但在输入m[]的值后,它似乎不接受任何值。
错误是:&#34; matright.exe已停止工作&#34;。 我输入的输入是: 3 2 3 1 2 3 0 1 2

3 个答案:

答案 0 :(得分:2)

第二个malloc

int **a=malloc(20*sizeof(int));

应该是

int **a=malloc(20*sizeof(int*));

第三个malloc

a[i]=malloc(sizeof(int));

仅为一个元素分配内存,但是您使用n循环进行此操作。

编辑(来自TobySpeight):

此外,阵列长度已经过硬编码。从循环中进一步猜测,你应该分配:

int *m = malloc(q * sizeof(int));
int **a = malloc(k * sizeof(int*));

第三个为

a[i] = malloc(n * sizeof(int));

答案 1 :(得分:0)

我不得不稍微修改你的程序,使它成为一个自包含的例子:它试图从stdin读取。所以我用这个函数的调用替换了scanf

int value()
{
    static int n = 0;
    return ++n;
}

我制作了nkq个常量:

    int n = 4;
    int k = 3;
    int q = 5;

现在,我可以在其上运行Valgrind,第一个错误是:

Invalid write of size 4  
   at 0x10861D: main (40159824.c:26)  
 Address 0x51d5134 is 0 bytes after a block of size 4 alloc'd  
   at 0x4C2ABAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)  
   by 0x108609: main (40159824.c:23)

第26行在这里:

    for (i=0;  i<n;  i++)
        a[0][i] = value();

并且它试图超出第23行分配的内存结束:

       a[i] = malloc(sizeof(int));

我们只为一个int分配了空间,但我们正在尝试编写n个空格。我们应该分配n倍的空间:

       a[i] = malloc(n * sizeof (int));

分配ma时会出现类似错误,这些错误被硬编码为不同于qn的倍数,这些倍数用作迭代的限制

修复这些错误后,我们得到:

Invalid write of size 8
   at 0x108610: main (40159824.c:23)
 Address 0x51d50a8 is 8 bytes inside a block of size 12 alloc'd
   at 0x4C2ABAF: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
   by 0x1085F4: main (40159824.c:19)

我们现在看到我们已经分配了

    int **a = malloc(k*sizeof(int));

但是a是指向int的指针,因此应该是k*sizeof(int*)

我们可以通过直接将a运算符应用于sizeof来让编译器执行此操作,而不必将计算保持与*a的声明同步:

    int **a = malloc(k * sizeof *a);

这个原则贯穿始终是最终的计划:

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

int value()
{
    static int n = 0;
    return ++n;
}


int main()
{
    int n = 4;
    int k = 3;
    int q = 5;
    int i,j;

    int *const m = malloc(q * sizeof *m);
    if (!m)
        return EXIT_FAILURE;

    int **const a = malloc(k * sizeof *a);
    if (!a)
        return EXIT_FAILURE;

    for (i=0;  i<k;  i++) {
        a[i] = malloc(n * sizeof *a[i]);
        if (!a[i])
            return EXIT_FAILURE;
    }

    for (i=0;  i<n;  i++)
        a[0][i] = value();

    for (i=0;  i<q;  i++)
        m[i] = value();

    for (i=0;  i<k;  i++) {
        for (j=0;  j<n;  j++) {
            if (j == n-1)
                a[i+1][0]=a[i][j];
            else
                a[i+1][j+1]=a[i][j];
        }

    }

    for (i=0;  i<q;  i++)
        printf("%d\n",a[k][m[i]]);

    return EXIT_SUCCESS;
}

现在,在循环的最后一次传递(a[i+1]i+1时)引用k之前,您不会收到任何错误。由于我不知道代码的意图(很难从单字母变量名称中提取代码),我不知道a是否应该更大,循环应该提前终止,或者其他完全终止,所以我留下来让你自己解决。

答案 2 :(得分:-1)

接受m[]的值后,没有代码可以接受值;其余的代码是计算&amp;输出