C 意外输出,为什么?

C 意外输出,为什么?,c,arrays,function,dynamic-memory-allocation,C,Arrays,Function,Dynamic Memory Allocation,这很简单,我使用函数分配一个动态2d数组。我限制了scanflen,我的问题是当输入的值超过限制时,会发生一些奇怪的事情 范例 输入:11122233444 预期产出:11,22,33,44 实际产出:11,12,33,34 #include <stdio.h> #include <stdlib.h> #define gd 2 void get_mem(int ***arr); void get_data(int **arr); int main(){ int

这很简单,我使用函数分配一个动态2d数组。我限制了scanflen,我的问题是当输入的值超过限制时,会发生一些奇怪的事情

范例 输入:11122233444 预期产出:11,22,33,44 实际产出:11,12,33,34

#include <stdio.h>
#include <stdlib.h>
#define gd 2

void get_mem(int ***arr);
void get_data(int **arr);

int main(){
    int **arr;
    arr = NULL;
    get_mem(&arr);
    get_data(arr);
    free(*arr);
    return 0;
}

void get_mem(int ***arr){
    int i;
    *arr =  (int**)malloc(gd*sizeof(int*));

for(i=0;i<5;i++){
    (*arr)[i] = (int*)malloc(gd*sizeof(int));
}
printf("oki\n");
}

void get_data(int **arr){
    int c,f;
    for(c=0;c<gd;c++){
        for(f=0;f<gd;f++){
            scanf("%2d",&*(*arr+c)+f);
            fpurge(stdin);
            fflush(stdin);          
        }
    }    
for(c=0;c<gd;c++){
    for(f=0;f<gd;f++){
        printf("%d ",*(*arr+c)+f);
        printf("\n");
    }

  }
}

我不想使用更多的指针,而是想这样做:-

#include <stdio.h>
#include <stdlib.h>
//#define gd 2
#define ROW 2
#define COLUMN 2

void get_mem(int ***arr);
void get_data(int **arr);

int main(){
    int **arr = NULL;
    get_mem(&arr);
    printf("Enter 4 int values: ");
    get_data(arr);
    free(*arr);
    return 0;
}

void get_mem(int ***arr)
{
    int i;
    *arr = ( int ** )malloc( ROW * sizeof(int *) );

    for(i = 0; i < COLUMN; i++)
    {
        (*arr)[i] = ( int * )malloc( COLUMN * sizeof(int) );
    }
    printf("Okay!\n");
}

void get_data(int **arr)
{
    int c, f;
    for(c = 0; c < ROW; c++)
    {
        for(f = 0; f < COLUMN; f++)
        {
            scanf("%2d", &arr[c][f]);   //*(*arr+c)+f)
        }
    }
    for(c = 0; c < ROW; c++)
    {
        for(f = 0; f < COLUMN; f++)
        {
            printf("%d ", arr[c][f]);   //*(*arr+c)+f)
        }
        putchar('\n');
    }
}
scanf("%2d", &(*(*(arr+c)+f)));
&

注意:另外,您应该在分配内存时检查是否有任何错误

希望有帮助。

宏gd的值是2。在get_mem中,为2 int*分配内存:

在其下方,访问超出其大小的arr:

for(i=0;i<5;i++){    //allocating memory to 5 int pointers
          ^^
    (*arr)[i] = (int*)malloc(gd*sizeof(int));
}
在get_数据中,访问arr元素以进行输入的方式是错误的

scanf("%2d",&*(*arr+c)+f);
            ^^^^^^^^^^^^ 
因为

&arr[c][f] --> &(*(arr[c] + f) --> &(*(*(arr + c) + f)) --> &*(*(arr + c) + f) --> (*(arr + c) + f)
注意:运算符&用于获取地址,运算符*用于解引用。当一个接一个地使用这些操作符时,它们会相互抵消效果。因此,&*arr+i等于arr+i

这意味着,&arr[c][f]相当于*arr+c+f,您应该使用&arr[c][f],它不太容易出错,而且可读性更高:

for(f = 0; f < gd; f++) {
    scanf("%2d", &arr[c][f]);
它应该是**arr+c+f。更具可读性的形式是arr[c][f]:

您不应该对输入流使用fflush。这是未定义的行为。来自C标准7.21.5.2p2-

如果流指向未输入最新操作的输出流或更新流,则fflush函数会导致将该流的任何未写入数据发送到主机环境,以写入文件;否则,行为是未定义的


此外,fpurge是非标准的,不可移植。此外,您不需要使用它们中的任何一个。

旁注:@Miguel Humberto This loop fori=0;i@MiguelHumberto我不知道你从哪里找到了这样一个最好的答案,但正如我所说的,这个程序有未定义的行为,没有意义。@MiguelHumberto在这个语句中arr=int*mallocgdsizeofint;您分配了一个包含两个指针的数组。但在这个循环中,i=0;i建议int**getmemvoid{…},然后在main中分配返回值,例如int**arr=getmem;成为一名教师通常不是一种恭维。不要忘记验证每个分配是否成功。我看到的更重要的一点是,不需要分配指针,然后再为int存储分配块。如果我理解,他们只是读取CSV并将每个CSV的前两个字符转换为int。所需的只是为int值分配一个块,而不是指针和int。只有当他们将每个CSV的前两个字符存储为字符串或原始字符或CSV的多行时,才需要这样做。但还不是100%清楚。@DavidC.Rankin谢谢,更正了。我同意您关于int值的单个块的分配,除了OP之外,其他人都没有询问解析此类输入的最佳/适当方式。OP ASQUED-我限制了扫描长度,我的问题是当输入的值超过限制时,会发生一些奇怪的事情,这是因为除了内存分配问题之外,一个不容易发现的错误。我希望OP能从我的回答中学到一些东西,增加他的知识。事实上,适当的方法是很好的补充,但我认为它超出了这个问题的范围。我喜欢这个答案,最大的问题是问题的清晰度。输入和输出是针对只有一行输入的MCVE,还是针对更大的集合。三星级程序员的方法也有点不可靠,但是你回答了一个直接的问题,即意外的输出,为什么?@HS这段代码就像是对我自己的测试,我试着开发一个等级表,或者类似的东西,为了保存像这样的勇气,我知道可以使用单指针避免所有这些,但对我来说是一个挑战。我在编程界相当新手,尽管这不能证明我愚蠢的问题和错误是正确的。感谢关于fpurge的帮助,我需要使用它,我不知道它是否是因为不使用c99,但如果我不使用它,缓冲区将填满,我只能读取2/4的值。我认为gd的目的是将每个逗号分隔值转换的字符数限制为2。这意味着如果读取了字符串1111,那么gd将把转换限制为11。但我并不完全清楚这一点。你对行和列的定义很好,我通常只使用行和列来保持整齐一致的间距,并传达复数而不是单数,但这只是一种习惯……是的,有时候,当我编写自己的代码时,就像开发新事物的挑战一样,我使用像gd这样的词,或者其他一些词,我的坏。但就像你说的,哥伦布和罗。是一个二维方形阵列2x2。谢谢你的帮助这是你的代码@MiguelHumberto,想用它做什么都行。但在上传任何问题之前,请帮我们一个忙,让这个社区的人们更容易阅读和理解。回答你的问题对我们很有帮助。
scanf("%2d",&*(*arr+c)+f);
            ^^^^^^^^^^^^ 
&arr[c][f] --> &(*(arr[c] + f) --> &(*(*(arr + c) + f)) --> &*(*(arr + c) + f) --> (*(arr + c) + f)
for(f = 0; f < gd; f++) {
    scanf("%2d", &arr[c][f]);
for(f=0;f<gd;f++){
    printf("%d ",*(*arr+c)+f);
                 ^^^^^^^^^^^
for(f = 0; f < gd; f++){
    printf("%d ", arr[c][f]);