C中具有大的,连续的2D阵列(具有动态存储器分配)的分段故障

时间:2015-09-14 19:31:46

标签: c arrays

下面的代码应该创建两个具有连续内存位置的2D数组(posa和posb),然后使用memmove函数将posa复制到posb上。令人惊讶的是,它适用于“小”数组大小(例如:size1 = size2 = 100),但我得到较大尺寸的分段错误(核心转储)(例如:size1 = size2 = 300)。 当我使用动态内存分配时,我认为这不是像here这样的堆栈溢出问题... 有人可以解释我做错了吗?

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

int ** Allocation_array_x2(int size1, int size2){
    int **ptr;
    int i;
    ptr = malloc(size1 * sizeof(*ptr));
    if(ptr == NULL)  {        
        fprintf(stderr,"Allocation error");
        exit(1);
    }
    ptr[0] = malloc(size1 * size2 * sizeof(**ptr));
    for(i=1 ; i < size1 ; i++){
        ptr[i]=ptr[0]+(i * size2);
        if( ptr[i] == NULL) {
            fprintf(stderr,"Allocation error");
            exit(1);
        }
    }
    return ptr;                         
}

void Free_array_x2(int **ptr){
    free(ptr);
    ptr=NULL;
}

int main(){
    int size1=300, size2=300;
    int **posa, **posb;
    posa=Allocation_array_x2(size1,size2);
    posb=Allocation_array_x2(size1,size2);

    /* array_filling */
    for( int j = 0 ; j<size1 ; j++ ) {
        for( int k = 0 ; k<size2 ; k++ ) {
            posa[j][k] = 2*j+3*k+1;     
            posb[j][k] = 1000;
        }
    }

    memmove(posb,posa,size1*size2*sizeof(int));

    for(int i = 0 ; i<size1 ; i++ ) {
        for(int j = 0 ; j<size2 ; j++ ) {
            printf("%d\t%d\n",posa[i][j],posb[i][j]);
        }
    }


    Free_array_x2(posa);
    Free_array_x2(posb);

}

2 个答案:

答案 0 :(得分:3)

将代码更改为此修复了它:

memmove(*posb,*posa,size1*size2*sizeof(int));

问题是您的主要内存块实际上位于posa[0]posb[0],而不是posaposbposaposb只是指向次要分配。

说到这一点,应该指出你正在泄漏内存 - 你的创建函数包含2个malloc调用,但你的自由函数只释放其中一个。

答案 1 :(得分:1)

错误在这里:

memmove(posb,posa,size1*size2*sizeof(int));

因为您将指针传递给指向整数的指针,但您应该将指针传递给整数:

memmove(*posb, *posa, size1 * size2 * sizeof(int));

您在Free_array_x2方法中也有错误,因为您没有通过malloc

释放您从系统中获取的所有内存
void Free_array_x2(int **ptr){
    free(ptr);
    ptr=NULL;
}

这应该转到您在分配例程中所做的事情:

void Free_array_x2(int **ptr)
{
    free(ptr[0]);
    ptr[0] = NULL;
    free(ptr);
    ptr = NULL;
}