Code Fix

中級

error: assignment of read-only location の原因と直し方

const int *pのように「指す先が変更不可」なポインタを介して、*pに値を書き込もうとしたときに出るエラーです。

エラーメッセージの読み方

main.c:6:8: error: assignment of read-only location '*p'
main.c
ファイル名
6
行番号
8
列番号 — この位置でgccが構文解析に失敗しました
assignment of read-only location '*p'
内容 — 期待していたもの、または受け付けられなかったもの

このエラーが出る典型パターン

パターン1

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int y = 1;
 5      const int *p = &y;
 6      *p = 2;
         ^
 7      printf("%d\n", *p);
 8      return 0;
 9  }
main.c:6:8: error: assignment of read-only location '*p'

const int *pは「指す先が読み取り専用」という意味です。値を変えたいときはポインタ経由ではなく、元の変数yを直接更新します。

直し方: *p を y にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int score = 10;
 5      const int *ptr = &score;
 6      *ptr   = 20;
           ^
 7      printf("%d\n", *ptr);
 8      return 0;
 9  }
main.c:6:10: error: assignment of read-only location '*ptr'

ptr自体を別のアドレスに向け直すことはできますが、指している先の値をptr経由で書き換えることはできません。

直し方: *ptr を score にします。

この問題を解いてみる →

パターン3

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int temp = 36;
 5      const int *reading = &temp;
 6      *reading = 40;
            ^
 7      printf("%d\n", *reading);
 8      return 0;
 9  }
main.c:6:14: error: assignment of read-only location '*reading'

読み取り専用の指す先を書き換えようとすると、コンパイル時にエラーとして検出されます。

直し方: *reading を temp にします。

この問題を解いてみる →

パターン4

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int z = 5;
 5      const int *q = &z;
 6      *q = 9;
         ^
 7      printf("%d\n", *q);
 8      return 0;
 9  }
main.c:6:8: error: assignment of read-only location '*q'

const int *qは指す先が読み取り専用という意味です。値を変えたいときは元の変数zを直接更新します。

直し方: *q を z にします。

この問題を解いてみる →

パターン5

 1  #include <stdio.h>
 2  
 3  int main(void) {
 4      int level = 3;
 5      const int *lp = &level;
 6      *lp    = 7;
           ^
 7      printf("%d\n", *lp);
 8      return 0;
 9  }
main.c:6:9: error: assignment of read-only location '*lp'

lp自体を別のアドレスに向け直すことはできますが、指している先の値をlp経由では書き換えられません。

直し方: *lp を level にします。

この問題を解いてみる →

よくある誤解

const int *pはポインタ自体は変更できてもよく(別のアドレスを指し直せる)、指す先の値だけが読み取り専用になります。ポインタ自体を固定したい場合はint * const pという別の書き方が必要で、両者は意味が逆であることに注意が必要です。

実務での勘所

const int *pとint * const pのどちらが何を固定するのかを覚えるコツは、constの直前(すぐ左側)にある要素を修飾すると考えることです。const int *pは、constのすぐ左に何も無く直後がintなので「intの部分(指す先の値)」を修飾し、int * const pはconstのすぐ左に*があるので「ポインタ自体」を修飾します。両方を固定したい場合はconst int * const pのように両方の位置にconstを置きます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)