GNU/Linux >> Belajar Linux >  >> Linux

Mencegah C integer overflow

Di C file header yang Anda inginkan adalah <stdint.h> dan konstantanya adalah UINT32_MAX

static void update_value(char op)
{
    if (op == '+')
        if ( value < (UINT32_MAX - 1))
            value++;    // uint32_t global value
        else
            printf("too big!\n");
    else
       if (value > 0)
           value--;
       else
           printf("too small!\n");
}

Untuk C++ Anda dapat menggunakan sejumlah solusi yang ditemukan di sini:Apa yang setara dengan C++ dari UINT32_MAX?


Saya telah menemukan bahwa solusi paling umum adalah memeriksa apakah nilai yang bertambah sebenarnya lebih besar dari nilai sebelumnya, atau jika nilai yang dikurangi lebih kecil dari nilai sebelumnya. Ini berfungsi hanya jika nilainya tidak ditandatangani , terlepas dari ukuran variabel, dan cukup portabel seperti yang pernah didapat kode C.

static void update_value(char op)
{
  if (op == '+') {
    if (value + 1 > value) value ++;
  } else {
    if (value - 1 < value) value --;
  }
}

Perhatikan bahwa kode dapat bekerja dengan nilai yang ditandatangani , tetapi menurut standar C ini akan menjadi perilaku yang tidak terdefinisi, dan kompiler bebas untuk mengganti if (value + 1 > value) ... dengan if (1) ... . Anda harus tidak gunakan kode ini dengan nilai yang ditandatangani kecuali Anda memiliki proses untuk mengaudit kode objek yang dihasilkan setelah ditautkan .

Dengan gcc dan dentang, Anda perlu menambahkan -fwrapv opsi untuk membiarkan kode ini berfungsi untuk nilai yang ditandatangani; dengan kompiler lain jarak tempuh Anda mungkin berbeda.

Cara waras untuk melakukan ini adalah dengan tipe spesifik dan menggunakan konstanta dari limits.h . Misalnya:

#include "limits.h"

static void update_int(char op, int *value)
{
  int val = *value; // ignoring NULL pointer dereference

  if (op == '+') {
    if (val != INT_MAX) *value = val + 1;
  } else {
    if (val != INT_MIN) *value = val - 1;
  }
}

static void update_int(char op, unsigned int *value)
{
  unsigned int val = *value; // ignoring NULL pointer dereference

  if (op == '+') {
    if (val != UINT_MAX) *value = val + 1;
  } else {
    if (val != UINT_MIN) *value = val - 1;
  }
}

Mungkin Anda sedang mencari <limits> :http://www.cplusplus.com/reference/limits/numeric_limits/

Anda dapat melakukan hal seperti ini untuk mendapatkan yang Anda inginkan:

unsigned int n = numeric_limits<unsigned int>::max()

Anda juga memiliki <cstdint> ini :http://www.cplusplus.com/reference/cstdint/

UINTN_MAX:Nilai maksimum dari tipe unsigned lebar-tepat (Persis 2^N-1)


Linux
  1. Gunakan Ts Tanpa Kehilangan Nilai Keluar?

  2. Urutkan Berdasarkan Nilai Hex?

  3. Bagaimana cara kerja "chmod -R 755"?

  1. Mencegah skrip bash berjalan secara bersamaan

  2. Nilai Maksimum Id Proses?

  3. Membulatkan angka yang dibagi dalam Bash

  1. Nilai persentase dengan GNU Diff

  2. PID maksimum di Linux

  3. menggunakan awk dengan kondisi nilai kolom