void型をキャストすることでint型やconst char型、ユーザー定義型に対応するcvectorというものを試作してみました。
ところが、PUSH_BACKマクロにてバッファオーバーランが発生したとの警告が発生してしまいます。
詳細を見てみると、
ARRAY_AT(T, tmp, i) = AT(T, CVECTOR, i);
AT(T, CVECTOR, CVECTOR.size_) = ITEM;
の二か所で「書き込み中にバッファオーバーランが発生しました。8バイト(テストケースの場合)を書き込む可能性があります。」という警告が出されています。
ITEMの代入はともかくとして、tmpとCVECTORは同じ型のはずなのに何故このような警告が出されているのでしょうか。
開発環境:VisualStudio2019 OS:Windows10
C
1// main.c 2#include <stdio.h> 3#include "cvector.h" 4 5int main(void) 6{ 7 cvector test; 8 INIT(test); 9 int size = 20; 10 for (int i = 0; i < size; i++) { 11 PUSH_BACK(int, test, i * i); 12 } 13 for (int i = 0; i < size; i++) { 14 printf("%d\n", AT(int, test, i)); 15 } 16 17 CLEAR(test); 18 return 0; 19}
C
1// cvector.h 2#pragma once 3#include <stdlib.h> 4#include <stdio.h> 5 6// C言語による簡易vectorもどき 7typedef struct cvector_t { 8 void* data_; // 要素の格納領域 9 int capacity_; // 格納可能な最大要素数 10 int size_; // 格納されている要素数 11} cvector; 12 13// 初期化 14#define INIT(CVECTOR) CVECTOR.data_ = 0; CVECTOR.capacity_ = 0; CVECTOR.size_ = 0; 15 16// 配列への参照(汎用) 17#define ARRAY_AT(T, V, N) ((T*)V)[N] 18 19// 要素への参照(cvector) 20#define AT(T, CVECTOR, N) ARRAY_AT(T, CVECTOR.data_, N) 21 22// 要素の末尾にデータを追加 23#define PUSH_BACK(T, CVECTOR, ITEM)\ 24{\ 25 if (CVECTOR.size_ == CVECTOR.capacity_) {\ 26 CVECTOR.capacity_ += 10;\ 27 void* tmp;\ 28 tmp = (T*)malloc(sizeof(T) * CVECTOR.capacity_);\ 29 if (tmp == NULL) { printf("memory secure error\n"); exit(1); }\ 30 for (int i = 0; i < CVECTOR.size_; ++i)\ 31 ARRAY_AT(T, tmp, i) = AT(T, CVECTOR, i);\ 32 FREE(CVECTOR);\ 33 CVECTOR.data_ = tmp;\ 34 }\ 35 AT(T, CVECTOR, CVECTOR.size_) = ITEM;\ 36 CVECTOR.size_++;\ 37} 38 39// 全ての要素を消去する 40#define CLEAR(CVECTOR) free(CVECTOR.data_); CVECTOR.capacity_ = 0; CVECTOR.size_ = 0; 41 42// data_のみを消去する 43#define FREE(CVECTOR) free(CVECTOR.data_);
回答1件
あなたの回答
tips
プレビュー