メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

未初期化ポインター

ポインターが読み取り前に初期化されない

説明

このチェックは、ポインターの読み取りのたびに行われます。これによって、読み取られるポインターが初期化されているかどうかを判別します。

すべて展開する

int assignValueToAddress(int *ptr) {
  *ptr = 0;
}

void main() {
 int* newPtr;
 assignValueToAddress(newPtr);
}

この例では、newPtrassignValueToAddress() に渡される前には初期化されません。

修正 — 関数に渡す前にポインターを初期化

1 つの修正方法として、assignValueToAddress() に渡す前に newPtr にアドレスを割り当てるとします。

int assignValueToAddress(int *ptr) {
  *ptr = 0;
}

void main() {
 int val;
 int* newPtr = &val;
 assignValueToAddress(newPtr);
}
#include <stdlib.h>
#define stackSize 25

typedef struct stackElement {
  int value;
  int *prev;
}stackElement;

int input();

void main() {
 stackElement *stackTop;
 
 for (int count = 0; count < stackSize; count++) {
    if(stackTop!=NULL) {
       stackTop -> value = input();
       stackTop -> prev = (int*)stackTop;
    }
    stackTop = (stackElement*)malloc(sizeof(stackElement));
 }
}

この例では、for ループの最初の実行において stackTop は初期化されておらず、有効なアドレスを指していません。したがって、stackTop!=NULL に対し [未初期化ローカル変数] チェックはレッド エラーを返します。

修正 — デリファレンスの前にポインターを初期化

1 つの修正方法として、チェック stackTop!=NULL の前に malloc() を介して stackTop を初期化するとします。

#include <stdlib.h>
#define stackSize 25

typedef struct stackElement {
  int value;
  int *prev;
}stackElement;

int input();

void main() {
 stackElement *stackTop;
 
 for (int count = 0; count < stackSize; count++) {
    stackTop = (stackElement*)malloc(sizeof(stackElement));
    if(stackTop!=NULL) {
       stackTop->value = input();
       stackTop->prev = (int*)stackTop;
    }
 }
}
#include <stdio.h>

void main() {
 char *str;
 scanf("%s",str);
}

この例では、str は有効なアドレスを指していません。したがって、関数 scanfstr への標準入力から文字列を読み取ると、[未初期化ポインター] チェックはレッド エラーを返します。

修正 — char* ポインターの代わりに char 配列を使用

1 つの修正方法として、strchar 配列として宣言するとします。この宣言により、配列名 str に関連付けられている char* ポインターにアドレスが割り当てられます。次に、そのポインターを scanf への入力として使用できます。

#include <stdio.h>

void main() {
 char str[10];
 scanf("%s",str);
}
#include <stdio.h>

void assignDataBaseElement(char** str) {
 scanf("%s",*str);
}

void main() {
 char *dataBase[20];

 for(int count = 1; count < 20 ; count++) {
    assignDataBaseElement(&dataBase[count]); 
    printf("Database element %d : %s",count,dataBase[count]);
 }
}

この例において、dataBasechar* ポインターの配列です。for ループの各実行では、dataBase の要素はポインターを介して関数 assignDataBaseElement() に渡されます。渡される要素は初期化されておらず、有効なアドレスを備えていません。したがって、要素を使用して標準入力からの文字列を保管すると、[未初期化ポインター] チェックはレッド エラーを返します。

修正 — calloc を介して char* ポインターを初期化

1 つの修正方法として、assignDataBaseElement() に渡す前に、関数 calloc() を介して dataBase の各要素を初期化するとします。calloc() を介して初期化することで、dataBase 内の char ポインターが可変サイズの文字列を指すようにできます。

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

void assignDataBaseElement(char** str) {
 scanf("%s",*str);
}
int inputSize();

void main() {
 char *dataBase[20];

 for(int count = 1; count < 20 ; count++) {
    dataBase[count] = (char*)calloc(inputSize(),sizeof(char));
    assignDataBaseElement(&dataBase[count]); 
    printf("Database element %d : %s",count,dataBase[count]);
 }
}

チェック情報

グループ: データ フロー
言語: C | C++
頭字語: NIP