NekoC

猫でもわかるC言語の個人的なまとめ資料

View on GitHub

11_高度なプログラミング2.md

メモリの動的確保

malloc関数

int *pi;
pi = (int *)malloc(sizeof(int));

void *malloc(
		size_t size
		);

free関数

void free(
		void *memlock
		);

perror関数

void perror(
		const char *string
		);

サンプルプログラム

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

int main(){
	int *pi, no, i;

	printf("いくつの整数値を入力しますか?--");
	scanf_s("%d", &no);
	pi = (int *)malloc(sizeof(int) *no);
	
	if (pi == NULL){
		perror("メモリの確保に失敗しました。");
		return -1;
	}
	for (i = 0; i < no; i++){
		printf("%d個目のデータ---", i + 1);
		scanf_s("%d", pi + i);
	}
	printf("入力されたデータは次の通り\n");
	for (i = 0; i < no; i++){
		printf("No.%d = %d\n", i + 1, *(pi + i));
	}
	free(pi);
	return 0;
}

出力結果

いくつの整数値を入力しますか?--5
1個目のデータ---1
2個目のデータ---2
3個目のデータ---3
4個目のデータ---4
5個目のデータ---5
入力されたデータは次の通り
No.1 = 1
No.2 = 2
No.3 = 3
No.4 = 4
No.5 = 5

calloc関数

int *pi;
pi = (int *)calloc(5, sizeof(int));
void *calloc(
		size_t size
		);

サンプルコード2

#include <stdio.h>
#include <malloc.h>
#include <string.h>

int main(){
	char *pc;
	pc = (char*)calloc(16, sizeof(char));
	if (pc == NULL){
		perror("メモリの確保に失敗しました。");
		return -1;
	}

	strcpy_s(pc,16, "あいうえお");
	printf("%s\n", pc);

	free(pc);
	return 0;
}

出力結果

あいうえお

確保領域の大きさを変更する

realloc関数

void *realloc(
		void *memlock,
		size_t size
		);

サンプルコード


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

int main(){
	double *pd, *pd2, sum = 0;
	int no = 0, i;
	char szData[32];

	pd = (double *)malloc(0);
	if (pd == NULL){
		perror("領域確保に失敗\n");
		exit(-1);
	}

	while (1){
		printf("数値を入力してください。(Eで終了): ");
		gets_s(szData);
		if (strcmp(szData, "E") == 0 || strcmp(szData, "e")==0){
			printf("入力を終了します。\n");
			break;
		}

		pd2 = (double *)realloc(pd, sizeof(double) * (no + 1));
		if (pd2 == NULL){
			perror("領域のサイズ変更に失敗しました。\n");
			free(pd); /*すでに確保してあるメモリを解放*/
			exit(-2);
		}
		pd = pd2;
		pd[no] = atof(szData);
		sum += pd[no];
		no++;
	}
	if (no){
		for (i = 0; i < no; i++){
			printf("No.%d %f\n", i + 1, pd[i]);
		}
		printf("合計\t%f\n", sum);
		printf("平均\t%f\n", sum/no);
	}
	free(pd);
	return 0;
}

出力結果

数値を入力してください。(Eで終了): 10
数値を入力してください。(Eで終了): 20
数値を入力してください。(Eで終了): 30
数値を入力してください。(Eで終了): e
入力を終了します。
No.1 10.000000
No.2 20.000000
No.3 30.000000
合計    60.000000
平均    20.000000
  1. pdに0のメモリ配列を確保
  2. whileが通るたびにpd2のメモリ配列を拡張
  3. pd2の拡張に成功した場合、pdpd2を代入。
    • pd = (double*)realloc(...)とした場合、拡張に失敗するとpdにNULLが代入されるため 確保してある領域に対してfree関数が無効になってしまう。