2015-10-17 111 views
0

当我喜欢运行代码如下:解放出来动态2D阵列未按预期用C

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

int main (void) 
{ 
    int i, count = 0x09; 
    int sizei = 5, sizej = 2; 

    int **ary = malloc (sizei * sizeof **ary); 
    for (i = 0; i < sizei; i++) { 
     *(ary + i) = malloc (sizej * sizeof *(ary + i)); 
     **(ary + i) = ++count; 
     printf (" %2d |%p| +%x+ \n", i, (ary + i), *(*(ary + i))); 
    } 

    puts("----"); 
    for (i = sizei - 1; i >= 0; i--) { 
     printf (" %2d |%p| +%x+ \n", i, (ary + i), *(*(ary + i))); 
     free (*(ary + i)); 
    } 
    puts("----"); 

    free (ary); 
    return 0; 
} 

我期望的是,第一半将产生整数称为ary的2D动态阵列(即一个指针一个动态分配的指针数组,每个指向一个动态分配的ints数组)。每个阵列**(ary + i)的第0个元素将被递归地分配的count当前值。

下半部分将反向迭代,释放每个元素ary,反过来它是malloc'd,然后释放ary本身。

这似乎做工精细,直到我尝试释放*(ary + 0),在这一点上,我得到一个双免费/损坏错误。我已经包含了输出。

0 |0x1d6f010| +a+ 
    1 |0x1d6f018| +b+ 
    2 |0x1d6f020| +c+ 
    3 |0x1d6f028| +d+ 
    4 |0x1d6f030| +e+ 
---- 
    4 |0x1d6f030| +e+ 
    3 |0x1d6f028| +d+ 
    2 |0x1d6f020| +c+ 
    1 |0x1d6f018| +b+ 
    0 |0x1d6f010| +1d6f0b0+ 
*** Error in `./a.out': double free or corruption (out): 0x0000000001d6f030 *** 

我很好奇为什么ary第0个元素的0号元素(即*(*(ary + 0) + 0))或只是**ary)成为什么样子一些内存地址(仅适用于性能稍微)出从什么就由这个二维数组边界一旦它退出第一个循环。

如果我摆脱了第二循环的,只是尝试直接免费ary没有首先释放的任何元素,我得到的是这样的:

0 |0x1d6f010| +a+ 
    1 |0x1d6f018| +b+ 
    2 |0x1d6f020| +c+ 
    3 |0x1d6f028| +d+ 
    4 |0x1d6f030| +e+ 
---- 
*** Error in `./a.out': free(): invalid next size (fast): 0x0000000001d6f010 *** 

我不明白我做了什么错这里。使用数组符号会有所作为吗?我需要的任何解决方案,让我有如果在所有可能的的ary其余元件的长度的每个阵列独立的的动态长度。的ary的数量的元件将不necesarily在编译时是已知的。如果这是相关的,我使用gcc 4.9。

回答

2

问题1

int **ary = malloc (sizei * sizeof **ary); 

相当于

int **ary = malloc (sizei * sizeof int); 

如果sizeof指针低于sizeof(int)在你的系统,你最终访问内存越界。

您需要使用:

int **ary = malloc (sizei * sizeof *ary); 

int **ary = malloc (sizei * sizeof(int*)); 

问题2

*(ary + i) = malloc (sizej * sizeof *(ary + i)); 

需求是

*(ary + i) = malloc (sizej * sizeof **(ary + i)); 

*(ary + i) = malloc (sizej * sizeof int); 

ary[i] = malloc (sizej * sizeof *ary[i]); 

ary[i] = malloc (sizej * sizeof int); 
0

ari是指针到指针的数组,所以元件的大小是指针。在代码中,使用sizeof **ary其为int

int **ary = malloc (sizei * sizeof **ary); 

对于每个指针int元件的阵列组成。在你的malloc对这些指针,你用sizeof *(ary+i)这是一个指向int

 *(ary + i) = malloc (sizej * sizeof *(ary + i)); 

的sizeof(int)的并不总是一样的sizeof(INT *)。事实上,在大多数64位的系统上,我怀疑你使用的是sizeof(int)== 4和sizeof(int *)== 8。我的猜测是你正在使用这样一个系统,因此,你不会为主ari指针分配足够的内存,并且你正在使用值溢出它,抖动关键内存管理数据的内容,以便将来的malloc ()和free()调用很有可能完全失败。