簡體   English   中英

訪問二維數組的正確方法 - C

[英]Correct way to access to 2D Array - C

讓我們想象一下我有這個動態分配的二維數組:

//Example of a 3 row * 2 columns int array
int (*arr)[2] = malloc(sizeof(int[3][2]));

但是,后來我發現如果我這樣做:

arr[0][5] = 1;

編譯器沒有抱怨,至少用 valgrind 測試,它也沒有抱怨。 除非我嘗試訪問超過分配空間大小的空間,否則不會。

我發現自動數組也會發生同樣的情況:

int arr[3][2];
arr[0][5] = 1; //Code works without errors 

我現在的問題是:例如聲明有什么意義: int arr[3][2]; 如果編譯器會接受arr[0][5] = 1; 反正?

我正在使用 GCC 編譯器

一般來說,不要超過你分配的內存邊界。

默認情況下,Clang 會警告這兩個示例,而 GCC 會在沒有實際使用變量的情況下警告這兩個示例(這是死代碼消除器的錯誤)。 如果使用變量或聲明為volatile您可以使用-O2 -Wall -Wextra啟用警告。

使用 GCC 和 Clang 這樣做是“安全的”; 每次都會發生同樣的事情。

然而,這是未定義的行為,所以這是一個壞主意。 對於執行此操作以使您的計算機長腿並走開的程序來說,這是完全有效的。

進行分配的等效方法是:

arr[2][1] = 1;

這是基於數組元素按順序存儲在內存中的假設。

因此, &arr[5][0]在技​​術上與&arr[2][1] ,但不應使用它。

我的建議:

int arr[3][2];
int x, y;

for( x = 0; x < 3; x++ )
    for( y = 0; y < 2; y++ )
        arr[x][y] = x * y;

這保證是安全的。

在我的電腦 Gcc 8.1.0

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

int main(){



    int i,j;
    int (*arr)[2] = malloc(sizeof(int[3][2]));
    printf("%p %d %d\n",arr,sizeof(int),sizeof(int[3][2]));
    //in my computer print 
    //00C63E38 4 24
    //legal memory from 00C63E38~00C63E4C 
    for(i=0;i<3;i++){
        for(j=0;j<2;j++){
            printf("%p ",&arr[i][j]);
        }
        printf("\n");
    }
    //00C63E38 00C63E3C 
    //00C63E40 00C63E44 
    //00C63E48 00C63E4C
    printf("------------------\n");
    for(i=0;i<3;i++){
        for(j=0;j<2;j++){
            printf("%p ",*(arr+i)+j);
        }
        printf("\n");
    }
    //00C63E38 00C63E3C 
    //00C63E40 00C63E44 
    //00C63E48 00C63E4C
    //So arr[i][j] is equel *(arr+i)+j
    printf("-------------\n");
    for(i=0;i<6;i++){
        printf("%p ",arr+i);
        printf("\n");
    }
    printf("-------------\n");
    //jump 4*2 pointer address per loop from 00C63E38
    //00C63E38 
    //00C63E40
    //00C63E48
    //00C63E50 
    //00C63E58
    //00C63E60
    for(i=0;i<6;i++){
        printf("%p ",arr[0]+i);
        printf("\n");
    }
    //jump 4 pointer address per loop from 00C63E38
    //00C63E38
    //00C63E3C 
    //00C63E40
    //00C63E44 
    //00C63E48
    //00C63E4C
    free(arr);

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM