2010-03-22 37 views
0

我有一个2D动态数组。 我输入线后面的线0的具有最大数量:内存中的未知错误C

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

,如果我做一个大小排列3,5,7,9,......它工作正常。但是,如果行数为2,4,6,...,它是一个访问冲突错误,当我尝试打印我的数组:

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

代码:http://codepad.org/JcUis6W4

+0

让我们来详细谈一下这个错误,谢尔盖。你得到的输出是什么,你期望的输出是什么? – ypnos

+0

当我尝试读取一个[0] [0]并且我的数组包含2,4,6,8,...行和colom时,出现访问冲突错误 –

+0

在我看来,您永远不会初始化任何分开一个[n-1]。所以我不知道你在哪里设置n,以及你在哪里调用InsertZero,但我认为你需要查看这个方向或者在这里发布代码。 – ypnos

回答

0

看着这个我无法理解....看看评论1,你有n设置为realloc一块内存,其中aint **类型 - 一个双指针,你怎么调用这个函数?其次,评论2,为什么当realloc上的双指针以前被调用时,你叫calloc ......?假设n具有值5,然后,realloc被称为双指针a,意为a[0][1]..a[4][1],现在calloc因此称为a[4]有一个新的内存块......

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

评论3,什么是用于d - 无用的变量? 注释4,假设n的值为5,则假定存储块的数组下标为[0][0][4][4]

你能澄清这一切吗?

编辑:再看一遍......当realloc的呼叫失败时,a可能被覆盖!我推荐的这部分代码来抵消这种

 
    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++){ 
      .... 
     } 
    } 
+0

1)“a”有“n-1”个元素,我用“realloc 2)a [n-1]调用一个新的记忆。 3)我有一个“n-1”行和“n”列。 “d”= 1,(n-d)是(n-1)。当我添加一个新行时,我使d = 0和“n”行和“n”列 4)我知道 –

0

在你的函数InsertZero你有一个局部变量a。这个局部变量最初被设置为指向一个整数的指针的地址(你可能想要一个指向整数数组的指针的地址,即int ***a)。

当你调用realloc要指定当地的a一个指向的内存块拷贝,但一旦你与你的函数完成了它是你本地的a副本完全有可能是指向其他不同的地方你的程序。你可能想说*a = (int **)realloc(a, n * sizeof(int *));

危险的是,你使用的是n,它不会传递给你的函数。看起来你已经假设n将比前一个数组大1 - 否则你对calloc的调用是多余的,你只是旋转数组,让最后一个元素作为内存泄漏丢弃。

让我们使用一个没有数组的简单示例,没有尺寸。比方说,你想创建一个函数:

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

不过你的情况,你只是分配a = realloc ...,因此从来没有沟通的a新地址的功能之外。

+0

我有一个“Magic num is 7” –

+0

尝试编写一些简单的测试代码Sergey,在使用多维数组和内存分配跳入深度之前,自己熟悉指针...... –

+1

PP有正确的想法。在Sergey的程序中,arr,n和d是全局变量。 arr被赋予指向CreateArray()中分配的指针数组的指针,但是当PP指出时,稍后当您重新分配时,您绝不会将结果赋给全局arr。我猜测,当n是偶数时,realloc必须将块移到其他地方,所以arr指向已释放的内存。 您必须检查* alloc的返回。此调用可能会失败并返回NULL。你的程序应该处理这个,也许以一个错误信息结束。使用有意义的变量名称,并避免使用全局变量。 – Fred