2012-11-03 50 views
0

所有不寻常的初始化麻烦

我写的动态二维数组声明的一个非常简单的C代码,并与memset初始化,然后打印出值。我的代码的东西如下:

float **env; 
int i,j,num; 

printf("Enter a number : \n"); 
scanf("%d",&num); 

env = (float **)malloc(num*sizeof(float *)); 

for(i=0;i<num;i++) 
{env[i] = (float *)malloc(num*sizeof(float));} 

memset(env, 0, sizeof(float)*num*num); 

for(i=0;i<num;i++) 
{ for (j=0;j<num;j++) 
    { 
     printf("%f\t",env[i][j]); 
     if (j == num -1) 
     { printf("\n\n");} 
    } 
} 

for(i=0;i<num;i++) 
{free(env[i]); 
} 

free(env); 

当我编译程序,没有编译错误或警告,但是当我尝试打印出来的值,我无法打印。然后我调试的程序,和ENV 2D可变正显示出类似 CXX0030: Error: expression cannot be evaluatedmemset语句后,当我打印值会出现一个窗口,显示

Unhandled exception at 0x008b1e27 in ***.exe: 0xC0000005: Access violation reading location 0x00000000.

我试图明确地初始化二维数组ENV为0使用2 for循环,它可以很好地工作,我也可以打印这些值,但是当我使用memset时它不起作用。如果有人能帮助我,那将会非常有帮助。谢谢。

回答

3

首先,通常的建议:停止使用sizeof下的类型名称并停止投射malloc的结果。这是它应该已经看起来像

env = malloc(num * sizeof *env); 

for (i = 0; i < num; i++) 
    env[i] = malloc(num * sizeof *env[i]); 

一般情况下,更愿意通过以下其次这种模式

some_ptr = malloc(N * sizeof *some_ptr); 

写你的内存分配,在“阵列”通过使用这种技术建立不一个经典的C型连续2D阵列。相反,你会从一堆完全不相关的一维数组中组装一个“模拟”二维数组。后者可能会随机散布在记忆中。这立即意味着您将无法将您的数组作为连续对象处理。同时你的memset呼叫试图做到这一点。你不能这样做。在你的情况下,你必须独立地使用一个循环来清零每个1D子阵列。

然而,代替独立地分配的1D子阵列,则可以对其进行分配所有为单个存储器块

assert(num > 0); 
env = malloc(num * sizeof *env); 
env[0] = malloc(num * num * sizeof *env[0]); 

for (i = 1; i < num; ++i) 
    env[i] = env[i - 1] + num; 

如果分配如上所示,则数组的数据将被存储在单个连续存储器块,尽管你仍然需要了解你在使用这个数组的时候正在做什么。例如,荷兰国际集团memset阵列数据将如下所示

memset(*env, 0, num * num * sizeof **env); 

memset(&env[0][0], 0, num * num * sizeof env[0][0]); 

(这是相同的东西)。

+0

感谢您的意见,我包括你在我的代码中提到的。所以考虑你所提到的,是否有任何方法将2D数组初始化为0而不明确使用2 for循环? – duttasankha

+1

@duttasankha:查看我答案的第二部分。你的代码是不可能的。但是如果你改变我的答案中所示的分配方案,它将成为可能。 – AnT

+0

感谢您的帮助。但是,当我停止铸造malloc然后我编译器扔我错误像 错误:类型“void *”的值不能分配给类型“浮动**”的实体 错误:值类型“void *“不能分配给”float *“类型的实体 我该怎么做才能做到这一点。我正在使用Microsoft Visual Studio 2010 – duttasankha

2

删除memset并使用calloc而不是malloc,它将分配的内存零初始化。你现在正在做的是调零你刚分配的指针。

+0

如果我删除了memset,那么我将如何初始化二维数组? – duttasankha

+1

再次阅读,calloc零初始化分配的内存 –

2

除了Michael的回答,重要的是要认识到float **env而不是给你一个连续的内存块。它会给你一个指向连续内存块的指针,并且在每个内存位置都有一个指向连续内存块的指针,但不能保证这些块是对齐的。

例如做:

int *x = malloc(sizeof(int)); 
int *y = malloc(sizeof(int)); 

x和y不能保证在内存中连续的,然而,这是你的代码是假设。