簡體   English   中英

試圖了解C中以下代碼的問題

[英]Trying to understand what is wrong with the following code in C

我有一個任務來查找為什么此代碼錯誤。

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

#define fail(a)          ((test == 0 || test == a) ? fail##a() : 0)
#define N                (10)

int  a[N] = { 1 }; 
int* b = &a[0];


void fail1()

{
    printf("a[0] = %d\n", a[0]);
    printf("b[0] = %d\n", b[0]);
    printf("*b   = %d\n", *b);
    *b = 2;
    a[N] = 3;
    printf("*b = %d\n", *b);

}

...

int main(int argc, char **argv)
{
    int        test = 0;

    if (argc > 1) {
            sscanf(argv[1], "%d", &test);
            printf("doing test %d\n", test);
    } else
            puts("doing all tests");

    fail(1);
    fail(2);
    fail(3);
    fail(4);
    fail(5);
    fail(6);

    puts("lab6 reached the end");

    exit(0);
}

通過使用valgrind,它告訴我printf("*b = %d\\n", *b);失敗printf("*b = %d\\n", *b); 我注意到,通過評論a[N] = 3; valvgrind沒有給出任何錯誤。 但是我不明白為什么。 我知道這與內存有關,我知道a[N]要求數組外的元素。

C數組具有從0開始的索引。 對於定義為a[N]的數組,最大有效元素將為a[N-1]

a[N]指向超出范圍的內存。 嘗試訪問超出范圍的內存會調用未定義的行為

現在,雖然您可能知道上述事實,但是您可能忽略了UB的作用。 一旦打到UB,便無法保證。 簡單的解決方案,不要編寫可以調用UB的代碼。

數組索引從0開始,因此最后一個索引aN-1N 通過寫入a[N]您正在訪問的內存不是數組的一部分,從而導致未定義的行為

C中沒有數組邊界檢查。a [N]位於數組末尾,即a [0] .. a [N-1]

如果您在數組范圍之外進行讀取或寫入,則會得到隨機結果(如今人們將UB稱為UB“未定義的行為”)。 這可能是

x = a[outside];

  • 代碼崩潰
  • 您得到一個隨機值
  • 您獲得了期望的價值

a[outside] = x;

  • 代碼崩潰
  • 發生寫入,但是回讀時該值已更改。
  • 發生寫操作,然后將其讀回即可(即,似乎什么也沒發生)
  • 發生寫操作,但是在代碼的其他部分出現崩潰。

例如,假設a []是char數組。

    a[0] | a[1] | ... | a[N-1] | s[0] | s[1] | s[2] | s[3] | s[4] | s[5]
    1    | 0    |     | 7      | 'H'  | 'e'  | 'l'  | 'l'  | '0'  | 0

寫入a [N]不會更改數組,而是會覆蓋另一個變量(在這種情況下,是字符串的一部分)。 您破壞了程序的內存,導致混亂。

    a[N] = 255;                 /*bug*/

    a[0] | a[1] | ... | a[N-1] | s[0] | s[1] | s[2] | s[3] | s[4] | s[5]
    1    | 0    |     | 7      | 255  | 'e'  | 'l'  | 'l'  | '0'  | 0

在此示例中,讀取和寫入a [N]似乎可以工作,但是它破壞了另一個字符串變量(該字符串變量以前表示“ Hello”,但現在沒有)。 這可能會在以后導致錯誤,或者也許多年來沒人會注意到!

使用C進行編程時,您需要格外小心和紀律。

暫無
暫無

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

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