为什么memset没有正确填充2D整数数组?

时间:2015-12-20 07:31:48

标签: c arrays

我使用int main(){ int** a = calloc( 2, sizeof(int*) ); int i = 0; for( ; i<2; i++ ){ a[ i ] = calloc( 2, sizeof( int ) ); } memset( a, 0, 4 * sizeof( int ) ) ; for( i = 0; i < 2; i++ ){ int j = 0; for( ; j < 2; j++ ){ printf( "%d ", a[i][j] ); } printf("\n"); } } 填充2D整数数组,如下所示。

memset( a, 0, 4 * sizeof( int ) )

输出:

  

分段错误

但如果我将for( i = 0; i < 2; i++ ){ int j = 0; for( ; j < 2; j++ ){ a[ i ][ j ] = 0; } } 替换为:

0 0 
0 0

输出正确:

memset()

有人可以告诉我为什么LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE); try { gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); }catch (Exception ex){} try{ network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER); }catch (Exception ex){} if(!gps_enabled && !network_enabled){ AlertDialog.Builder dialog = new AlertDialog.Builder(this); dialog.setMessage(getResources().getString(R.string.gps_network_not_enabled)); dialog.setPositiveButton(getResources().getString(R.string.open_location_settings), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface paramDialogInterface, int paramInt) { Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS); Startup.this.startActivity(myIntent); } }); dialog.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface paramDialogInterface, int paramInt) { // TODO Auto-generated method stub } }); dialog.show(); } 在那里不起作用吗?

3 个答案:

答案 0 :(得分:4)

在分配内存时,您已将2, sizeof(int*)金额分配给a,而在执行memset()时,您使用4 * sizeof(int)。它们必然不代表相同数量的内存(更重要的是,甚至不是你想要的内存)因此会分配内存过多。这会调用导致分段错误的undefined behavior

话虽如此,你不需要memset() calloc()内存为0.已经是。

答案 1 :(得分:4)

当你这样写的时候

int** a = calloc( 2, sizeof(int*) );
int i = 0;
for( ; i<2; i++ ){
    a[ i ] = calloc( 2, sizeof( int ) );
}

你得到的内存就是这样的

        +--+       +--+--+
a[0]    |  |-----> |  |  |
        +--+       +--+--+ 
a[1]    |  |   
        +--+  
            \      +--+--+
             +---> |  |  |
                   +--+--+  

memset期望内存成为一个连续的内存块,但事实并非如此 你正在给它,所以memset(a,0,4*sizeof(int))你正在写作 a [1]蓝色。

使用[0] [1]你正在进行两次推理,一次用于第一个向量a [0] .. a [1] 和第二个向量的一个,这就是为什么它在你的for循环中工作。

答案 2 :(得分:2)

无法保证所有不同的分配都是相互连续的。正确初始化内存的唯一方法是初始化已分配的每个部分。您可以使用memset,但这样:

    int** a = calloc( 2, sizeof(int*) );
    memset( a, 0, 2 * sizeof( int* ) ) ;     // initialize the two pointers
    int i = 0;
    for( ; i<2; i++ ){
        a[ i ] = calloc( 2, sizeof( int ) );
        memset( a[i], 0, 2 * sizeof( int ) ) ;  // initializes the two ints
    }

请注意,由于您使用了calloc,因此无需初始化为零。