开发者

Unknown error in the memory in C

开发者 https://www.devze.com 2022-12-23 23:51 出处:网络
I have a 2D dynamic array. I enter a line of 0\'s after line which has a biggest number: void InsertZero(int **a, int pos){

I have a 2D dynamic array. I enter a line of 0's after line which has a biggest number:

void InsertZero(int **a, int pos){
    int i, j;
    a = (int**)realloc(a, n * sizeof(*a));
    a[n-1] = (int*)calloc(n, sizeof(**a));
    d = 0;
    for(i = n-1; i > pos; i--){
        for(j =开发者_StackOverflow社区 0; j < n; j++){
            a[i][j] = a[i-1][j];
            printf("%d ", a[i][j]);
        }
    }

    for(i = 0; i < n; i++){
        a[pos][i] = 0;
    }
}

If i make a size of array 3, 5, 7, 9, ... it works correctly. But if a number of lines is 2, 4, 6, ... , it is an access violation error, when i try to print my array:

void Print(void){
    int i, j;
    for(i = 0; i < (n-d); i++){
        for(j = 0; j < n; j++){
            printf("%d\t", arr[i][j]);
        }
        printf("\n");
    }
}

code: http://codepad.org/JcUis6W4


Looking at this I cannot make sense of.... Look at comment 1, you have n set somewhere to realloc a block of memory which a is of type int ** - a double pointer, how are you calling this function? Secondly, comment 2, Why did you call calloc when the realloc on a double pointer was called previously...? Assume n has value of 5, then, realloc is called on double pointer a, meaning a[0][1]..a[4][1], now calloc is called thus a[4] has a new block of memory...

void InsertZero(int **a, int pos){
    int i, j;

    /* 1. */
    a = (int**)realloc(a, n * sizeof(*a)); 
    /* Bzzzzt....if realloc failed, a gets overwritten! */

    /* 2. */
    a[n-1] = (int*)calloc(n, sizeof(**a));

    /* 3. */
    d = 0;

    /* 4. */
    for(i = n-1; i > pos; i--){
        for(j = 0; j < n; j++){
            a[i][j] = a[i-1][j];
            printf("%d ", a[i][j]);
        }
    }

    for(i = 0; i < n; i++){
        a[pos][i] = 0;
    }
}

Comment 3, what is d used for - useless variable? Comment 4, you are under the presumption that the block of memory has array subscripts [0][0] to [4][4] if n had a value of 5!

Can you clarify all this?

Edit: Looking at it again... it is likely that a got overwritten when the call to realloc failed! I recommend this section of code to counteract this

    int **tmpA;
    tmpA = (int**)realloc(a, n * sizeof(*a)); 
    if (tmpA != NULL){
        a = tmpA;
        ....
        a[n-1] = (int*)calloc(n, sizeof(**a));
        for(i = n-1; i > pos; i--){
            .... 
        }

        for(i = 0; i < n; i++){
            ....
        }
    }   


In your function InsertZero you have a local variable a. This local variable is initially set with a the address of a pointer to an integer (you probably wanted the address of a pointer to an array of integers, i.e. int ***a).

When you call realloc you are assigning your local copy of a a pointer to a block of memory, however once you have finished with your function it is entirely possible for your local copy of a to be pointing somewhere different to the rest of your program. You probably wanted to say *a = (int **)realloc(a, n * sizeof(int *));.

Dangerously, you're using n which isn't passed to your function. It appears you've made the assumption that n is going to be 1 bigger than the previous size of the array - otherwise your call to calloc is superfluous and you are just rotating the array letting the last element drop off as a memory leak.

Let's use a simpler example with no arrays, no dimensions. Let's say you wanted to create a function:

void make_me_a_pointer( int **mynumber ) {
    *mynumber = (int *)malloc( sizeof(int) );
    **mynumber = 7; /* assign the value 7 to my allocated memory */
}

int main( void ) {
    int *demoint;
    make_me_a_pointer( &demoint );
    printf( "Magic num is %d\n", *demoint );
}

However in your case you merely assigned a = realloc... and thus never communicated the new address of a outside your function.

0

精彩评论

暂无评论...
验证码 换一张
取 消