Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
realloc 2 dim阵列分段故障,但输出正确?_C_Arrays_Segmentation Fault_Malloc_Realloc - Fatal编程技术网

realloc 2 dim阵列分段故障,但输出正确?

realloc 2 dim阵列分段故障,但输出正确?,c,arrays,segmentation-fault,malloc,realloc,C,Arrays,Segmentation Fault,Malloc,Realloc,嗨,我有一个问题,因为我不明白为什么我的C程序有一个分段错误。我的程序创建了一个2维整数数组,每一行都将被固定大小的5进行malloced,并且每一行中都有随机数。但是用户可以选择,如果他想在一行中输入超过5 int的值,如果他想我重新定位我的行。每行长度都存储在数组大小中。因此,输出很好:例如 1,6,3,4 8,6,5,3,2,1,6,8,9 1,4 8,9,6,4,2 但在输出后,我的程序以分段错误结束,但为什么??我的错误是在自由函数中还是在我的输出中??谢谢你的回答和我糟糕的英语: #

嗨,我有一个问题,因为我不明白为什么我的C程序有一个分段错误。我的程序创建了一个2维整数数组,每一行都将被固定大小的5进行malloced,并且每一行中都有随机数。但是用户可以选择,如果他想在一行中输入超过5 int的值,如果他想我重新定位我的行。每行长度都存储在数组大小中。因此,输出很好:例如 1,6,3,4 8,6,5,3,2,1,6,8,9 1,4 8,9,6,4,2

但在输出后,我的程序以分段错误结束,但为什么??我的错误是在自由函数中还是在我的输出中??谢谢你的回答和我糟糕的英语:

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

void flushi(){// to flush the buffer 
char buff = ' ';
    while ((buff = getchar()) != '\n' &&buff !=EOF);
    return;
}
void freeall(int **arr,int zeilen){
    for (int i = 0; i < zeilen; i++) { 
        free(arr[i]);
    }
    free(arr);
}

int main(){
    int zeilen=4;
    int d,j;
    srand(time(0));
    int spalten=5;
    int size[spalten];
    int **arr=malloc(sizeof(int*)*4);
    for(int i=0;i<zeilen;i++){
        arr[i]=(int*)malloc(sizeof(int*)*spalten);// malloc first line
        j=0;
        while(1){
            printf("Wollen sie noch eine Zahl eingeben\n");
            printf("1...Ja      0...Nein\n");
            scanf("%i",&d);
            flushi();
            if(d==1){
                if(j>=spalten){// if user want more than 5 int in one line
                    spalten++;
                    arr[i]=realloc(arr[i],sizeof(int)*spalten);// realloc line
                }
                arr[i][j]= (rand()%10)+1;
                j++;
                printf("Sie haben schon %i Zahlen eingegeben\n",j);
            }
            else{
                break;
            }
        }
        size[i]=j;
    }
    printf("Your Numbers\n");
    for (int h=0;h<spalten;h++){
        printf("\n");
        for (int g=0;g<size[h];g++){
            printf("%i ",arr[h][g]);
        }
    }
    printf("\n");
    freeall(arr,zeilen);
    return EXIT_SUCCESS;
}

我认为,问题在于

for (int h=0;h<spalten;h++)

抱歉,我也不是以英语为母语的人

printfWollen sie noch eine Zahl eingeben\n;是否打印您要添加一个数字\n打印Sie haben schon%i Zahlen eingegeben\n,j;这是一个你在一行中输入了多少数字的信息逻辑上,arr[i]=int*mallocsizeofint**spalten;应为arr[i]=mallocsizeofint*spalten;但随后出现了以下警告:p.c:25:9:error:赋值从整数生成指针,但没有强制转换[-Werror]arr[i]=intmallocsizeofint*spalten;//malloc一线OK对不起;我已经完成了你的任务correction@rem很高兴这有帮助。干杯-
for (int h=0;h<4;h++)
There are several problems.
I have added comments about some of the problems to the original code

Please comment your code, for two major reasons
1) so in a few months you do not have to reverse engineer the code
2) so I do not have to reverse engineer your code 
   so that I can helpfully comment on what went wrong in the code

Note: getchar returns a int value, not a char value
      and '\n' on certain OSs is 2 characters
      and EOF is -1, not a char

The second code group is a suggested fix
In the second code group, there are certain improvements

that could be easily made,  
For instance, eliminate the spalen variable
allocate for the rows only once via:

if user enters 0,  
then use the default length, 
otherwise the user entered length


----Original code group with some comments----

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

void flushi()
{// to flush the buffer 
    char buff = ' ';

    while ((buff = getchar()) != '\n' &&buff !=EOF);
} // end function: flushi


void freeall(int **arr,int zeilen)
{
    for (int i = 0; i < zeilen; i++)
    { 
        free(arr[i]);
    }
    free(arr);
} // end function: freeall


int main()
{
    int zeilen=4;
    int d,j;

    srand(time(0)); // should be srand( time( NULL ) );

    int spalten=5;
    int size[spalten];

    int **arr=malloc(sizeof(int*)*4); // allocate room for 4 pointers to integers
       // should always test returned value from malloc to assure operation successful

    for(int i=0;i<zeilen;i++) // foreach of the 4 pointers to integers
    {
        arr[i]=(int*)malloc(sizeof(int*)*spalten);// ERROR: allocate room for 5 pointers to intege
             // should be: arr[i] = malloc( sizeof(int)*spalten); // allocate room for 5 integers
             // should always test returned value from malloc to assure operation successful

        j=0;

        while(1)
        {
            printf("Wollen sie noch eine Zahl eingeben\n");
            printf("1...Ja      0...Nein\n");
            scanf("%i",&d);
                // should always test returned value from scanf to assure operation successful

            flushi();

            if(d==1) // 
            {
                if(j>=spalten)
                {// if user want more than 5 int in one line
                    spalten++;
                    arr[i]=realloc(arr[i],sizeof(int)*spalten);// realloc line
                        // always test returned value from realloc before
                        // 1) to assure operation was successful
                        // 2) before using the new pointer
                        //    otherwise old allocation lost, resulting in a memory leak
                } // end if

                arr[i][j]= (rand()%10)+1;
                j++;
                printf("Sie haben schon %i Zahlen eingegeben\n",j);
            }

            else
            { // else, user did not enter 1 ????
                break;
            } // end if
        } // end while

        size[i]=j; // remember/ save meaningless number
    } // end for

    printf("Your Numbers\n");

    for (int h=0;h<spalten;h++) // foreach 0...4
    {
        printf("\n");

        for (int g=0;g<size[h];g++) // for each 0...meaningless value
        {
            printf("%i ",arr[h][g]);
        } // end if
    } // end for

    printf("\n");

    freeall(arr,zeilen);

    return EXIT_SUCCESS;
} // end function: main

----second code group which is a suggested fix----

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

void flushi()
{// to flush the buffer
    int buff;
    while ((buff = getchar()) != '\n' &&buff !=EOF);
} // end function: flushi


void freeall(int **arr,int rowCount)
{
    // free each row
    for (int i = 0; i < rowCount; i++)
    {
        free(arr[i]); // note: ok to call free() with null pointer
    }

    // free the array
    free(arr);
} // end function: freeall


#define MAX_ROWS (4)
#define DEFAULT_ROW_LEN (5)

// notice the removal of unneeded variables

// notice that most features are implemented 
// in separate code blocks

int main()
{
    int rowLength;  // new length (of integers) for each row
    int i, j;       // loop index/counters

    int spalten=DEFAULT_ROW_LEN;  // default length (of integers) for each row

    int size[MAX_ROWS] = {0};  // save area for final length of each row

    int **arr = NULL;
    if( NULL == (arr=malloc(sizeof(int*)*MAX_ROWS) ) ) // allocate room for MAX_ROWS pointers to integers
    { // then malloc failed
        perror( "malloc failed for number of rows" );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    // clear first memory allocation (int pointers) to NULLs
    memset( arr, 0x00, MAX_ROWS*sizeof(int*) );

    for(i=0; i<MAX_ROWS; i++) // foreach of the rows
    {
        if( NULL == (arr[i]=malloc(sizeof(int)*spalten) ) )
        { // then, malloc failed
            perror( "malloc failed for row" );
            freeall( arr, MAX_ROWS ); // cleanup
            exit( EXIT_FAILURE );
        }

        // implied else, malloc successful

        size[i] = spalten;

    } // end for each row

    srand( time( NULL ) );

    for( i=0; i<MAX_ROWS; i++) // foreach row
    {
        printf("Wollen sie noch eine Zahl eingeben\n");
        printf("1...Ja      0...Nein\n");

        if( 1 != scanf("%i",&rowLength) )
        { // then scanf failed
            perror( "scanf failed for row length" );
            freeall( arr, MAX_ROWS ); // cleanup
            exit( EXIT_FAILURE );
        }

        // implied else, scanf successful

        flushi();

        if( rowLength > 0) // 0 means no change and negative numbers are ignored
        { // then, user wants a different length for this row

            if(rowLength != spalten)
            {
                size[i] = rowLength;
                int * temp;

                // if user want other than 5 int in one row
                if( NULL == (temp = realloc(arr[i],sizeof(int)*rowLength) ) )
                { // then, realloc failed
                    perror( "realloc failed for row length change" );
                    freeall( arr, MAX_ROWS ); // cleanup
                    exit( EXIT_FAILURE );
                }

                // implied else, realloc successful

                arr[i] = temp; // update the pointer in the array
            } // end if
        } // end if

        // fill in row of arr with random values
        for( j = 0; j<size[i]; j++ )
        {
            arr[i][j]= (rand()%10)+1;
        } // end if

        printf("Sie haben schon %i Zahlen eingegeben\n",j);
    } // end for

    printf("Your Numbers\n");


    for (int i=0;i<MAX_ROWS;i++) // foreach row
    {
        printf("\n");

        for (int j=0;j<size[i];j++)
        {
            printf("%i ",arr[i][j]);
        } // end if
    } // end for

    printf("\n");

    freeall(arr,MAX_ROWS); // cleanup

    return EXIT_SUCCESS;
} // end function: main