【问题标题】:Segmentation fault with large, contiguous 2D array (with dynamic memory allocation) in CC 中大型连续二维数组(具有动态内存分配)的分段错误
【发布时间】:2015-09-14 19:31:45
【问题描述】:

下面的代码应该创建两个具有连续内存位置的二维数组(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);

}

【问题讨论】:

  • 细分到底发生在哪里?
  • 第二个malloc 的检查必须在ptr[0] 上。如果不是NULL,则所有后续指针都不是NULL。你的free 方法应该是free ptr[0]ptr
  • 是的,这是内存泄漏,您只需对两个 malloc 进行一次免费调用
  • 如果要将所有需要的内存分配给ptr[0],然后将其分配给其他数组元素(为了保持连续性),我觉得处理它会更好作为一维数组并使用 row*size2+col 来操作索引。

标签: c arrays


【解决方案1】:

将代码更改为此为我解决了问题:

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

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

说到这里,应该指出您正在泄漏内存——您的 create 函数包含 2 个 malloc 调用,但您的 free 函数只释放其中一个。

【讨论】:

    【解决方案2】:

    错误在这里:

    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;
    }
    

    【讨论】:

    • 谢谢!!!你们真是太棒了!恐怕指针与数组括号 [] 表示法相结合的东西远远超出了我的范围。我无法解释为什么它确实适用于小数组大小?!内存分配的奥秘……
    猜你喜欢
    • 2014-06-15
    • 2013-05-27
    • 2021-12-02
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2013-09-04
    • 2012-11-12
    • 2020-08-08
    相关资源
    最近更新 更多